请在我输入所有数据后,当我尝试保存我的数据输入表格(复杂表格)时,请帮助我了解我出错的地方以便收到此消息?
我有五个模型如下:
class Contract < AR::Base
has_many :clientlines
has_many :codelines
has_many :clients, :through => :clientlines
has_many :codes, :through => :codelines
accepts_nested_attributes_for :clientlines
end
class Clientline < AR::Base
belongs_to :contract
belongs_to :client
accepts_nested_attributes_for :contract
end
class Client < AR::Base
has_many :clientlines
has_many :contracts, :through => :clientlines
end
class Codeline < AR::Base
belongs_to :contract
belongs_to :code
units_alloc
accepts_nested_attributes_for :code
end
class Code < AR::Base
has_many :codelines
has_many :contracts, :through => :codelines
end
我使用以下文章作为我的设计来源:
http://rubysource.com/complex-rails-forms-with-nested-attributes/
在我的app / controller / contracts_controller.rb中,我有以下内容:
def new
@contract = Contract.new
4.times { @contract.codes.build }
4.times { @contract.codelines.build }
end
def create
@contract = Contract.new(params[:contract])
if @contract.save
flash[:success] = "New Contract has been saved"
redirect_to @contract # this redirects to the contract show page
else
@title = "You have some errors"
render 'new'
end
end
.
.
.
end
我将复杂的表格放在一起如下:
- provide(:title, 'Add Contract')
%h2 New Contract
=form_for(@contract) do |f|
=render 'shared/contract_error_messages', object: f.object
=render 'fields', f: f
.actions
= f.submit "Save", class: 'save strong round'
部分_fields:
<fieldset><legend>Enter Contract Details</legend>
.field
= f.label :name, "AuthNum"
%br/
= f.text_field :authnum, :size => 10, :class => "ui-state-default"
.field
= f.label :name, "Start Date"
%br/
= f.text_field :st_date, :size => 12, :class => "ui-state-default"
.field
= f.label :name, "End Date"
%br/
= f.text_field :end_date, :size => 12, :class => "ui-state-default"
</fieldset>
<fieldset><legend>Enter Client Details</legend>
= f.fields_for :clients do |ff|
.field
= ff.label :name, "First Name"
%br/
= ff.text_field :f_name, :size => 15, :class => "ui-state-default"
.field
= ff.label :name, "MI"
%br/
= ff.text_field :mi, :size => 3, :class => "ui-state-default"
.field
= ff.label :name, "Last Name"
%br/
= ff.text_field :l_name, :size => 15, :class => "ui-state-default"
.field
= ff.label :name, "Birth Date"
%br/
= ff.text_field :birth_date, :size => 12, :class => "ui-state-default"
.field
= ff.label :name, "Address1"
%br/
= ff.text_field :address1, :size => 25, :class => "ui-state-default"
.field
= ff.label :name, "Address2"
%br/
= ff.text_field :address2, :size => 25, :class => "ui-state-default"
.field
= ff.label :name, "City"
%br/
= ff.text_field :city, :size => 15, :class => "ui-state-default"
.field
= ff.label :name, "ZipCode"
%br/
= ff.text_field :zip_code, :size => 10, :class => "ui-state-default"
.field
= ff.label :name, "State"
%br/
= ff.text_field :state, :size => 15, :class => "ui-state-default"
.field
= ff.label :name, "MedicareNum"
%br/
= ff.text_field :medicarenum, :size => 20, :class => "ui-state-default"
.field
= ff.label :name, "MedicaidNum"
%br/
= ff.text_field :medicaidnum, :size => 20, :class => "ui-state-default"
.field
= ff.label :name, "MemberNum"
%br/
= ff.text_field :membernum, :size => 20, :class => "ui-state-default"
.field
= ff.label :name, "SocSerCareMgr"
%br/
= ff.text_field :socsercaremgr, :size => 20, :class => "ui-state-default"
.field
= ff.label :name, "SSCM_Ph"
%br/
= ff.text_field :sscm_ph, :size => 15, :class => "ui-state-default"
.field
= ff.label :name, "NurseCareMgr"
%br/
= ff.text_field :nursecaremgr, :size => 20, :class => "ui-state-default"
.field
= ff.label :name, "NCM_Ph"
%br/
= ff.text_field :ncm_ph, :size => 15, :class => "ui-state-default"
.field
= ff.label :name, "EmergencyContact"
%br/
= ff.text_field :emergencycontact, :size => 20, :class => "ui-state-default"
.field
= ff.label :name, "EC_Ph"
%br/
= ff.text_field :ec_ph, :size => 15, :class => "ui-state-default"
.field
= ff.label :name, "PrimaryCarePhy"
%br/
= ff.text_field :primarycarephy, :size => 20, :class => "ui-state-default"
.field
= ff.label :name, "PCPhy_Ph"
%br/
= ff.text_field :pcphy_ph, :size => 15, :class => "ui-state-default"
</fieldset>
<fieldset><legend>Enter Billing Code Details</legend>
= f.fields_for :codes do |ff|
.field
= ff.label :name, "Code Name"
%br/
= ff.text_field :code_name, :size => 15, :class => "ui-state-default"
.field
= ff.label :name, "Status"
%br/
= ff.text_field :status, :size => 10, :class => "ui-state-default"
.field
= ff.label :name, "Description"
%br/
= ff.text_field :description, :size => 25, :class => "ui-state-default"
= f.fields_for :codelines do |ff|
.field
= ff.label :name, "Units Alloc"
%br/
= ff.text_field :units_alloc, :precision => 6, :scale => 2, :size => 10, :class =>
"ui-state-default"
</fieldset>
我的首要问题是,一旦我输入了表单上的所有数据,然后按下“保存”即可。按钮我得到以下内容:
CollactsController中的ActiveRecord :: Association TypeMisMatch #Create。 预期客户端(#xxxxxx),得到阵列(#xxxxxx)。
另一个问题是,如果我包含&#39; accepts_nested_attributes_for:codelines&#39;在我的合约模型中,&#39; units_alloc&#39;属性从我的表单中消失。
在这两个问题上,我们将非常感谢任何帮助或指导。我花了一些时间阅读复杂的表格,观看了复杂的表格和#39;我已阅读并重新阅读关于关联的Rails指南以及accept_nested_attributes_for方法的API文档。显然,我对这些概念的理解还没有达到解决这些问题所需的全面理解,因此我呼吁帮助。
更新 应用程序/控制器/ contracts_controller.rb
class ContractsController < ApplicationController
def index
@contracts = Contract.paginate(page: params[:page])
end
def show
@contract = Contract.find(params[:id])
end
def new
@contract = Contract.new
@contract.codes.build
@contract.codelines.build
@contract.clients.build
end
def create
raise params[:contract].to_s ------ **this is line #19**
@contract = Contract.new(params[:contract])
if @contract.save
flash[:success] = "New Contract has been saved"
redirect_to @contract # this redirects to the contract show page
else
@title = "You have some errors"
render 'new'
end
end
def edit
@contract = Contract.find(param[:id])
end
def update
if @contract.update_attributes(params[:contract])
flash[:success] = "Contract Profile updated"
redirect_to @contract
else
render 'edit'
end
end
end
我添加了&#34;提升参数[:contract] .to_s&#34;作为我在contract_controller.rb中创建操作的第一行,输出如下:
RuntimeError in ContractsController#create
{"authnum"=>"700900", "st_date"=>"04/03/2012", "end_date"=>"06/29/2012", "clients"=>
{"f_name"=>"Lefty", "mi"=>"L", "l_name"=>"Right", "birth_date"=>"07/18/1979",
"address1"=>"54 Frosty Lane", "address2"=>"", "city"=>"Frave", "zip_code"=>"54806",
"state"=>"WI", "medicarenum"=>"789987456", "medicaidnum"=>"931579135",
"membernum"=>"890333-3", "socsercaremgr"=>"Caring Serving",
"sscm_ph"=>"1-444-444-4444", "nursecaremgr"=>"Caring Nurse",
"ncm_ph"=>"1-555-555-5555", "emergencycontact"=>"Quick Response",
"ec_ph"=>"1-666-666-6666", "primarycarephy"=>"This One", "pcphy_ph"=>"1-777-777-7777"},
"codes"=>{"code_name"=>"S-5463", "status"=>"Active", "description"=>"Transition from
sch to mkt"}, "codelines"=>{"units_alloc"=>"80.00"}}
Rails.root: /home/tom/rails_projects/tracking
Application Trace | Framework Trace | Full Trace
app/controllers/contracts_controller.rb:19:in `create'
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"/i21h2vwzuDPjIrCXzYEIAg41FnMxfGdCQQggjqcZjY=",
"contract"=>{"authnum"=>"700900",
"st_date"=>"04/03/2012",
"end_date"=>"06/29/2012",
"clients"=>{"f_name"=>"Lefty",
"mi"=>"L",
"l_name"=>"Right",
"birth_date"=>"07/18/1979",
"address1"=>"54 Frosty Lane",
"address2"=>"",
"city"=>"Frave",
"zip_code"=>"54806",
"state"=>"WI",
"medicarenum"=>"789987456",
"medicaidnum"=>"931579135",
"membernum"=>"890333-3",
"socsercaremgr"=>"Caring Serving",
"sscm_ph"=>"1-444-444-4444",
"nursecaremgr"=>"Caring Nurse",
"ncm_ph"=>"1-555-555-5555",
"emergencycontact"=>"Quick Response",
"ec_ph"=>"1-666-666-6666",
"primarycarephy"=>"This One",
"pcphy_ph"=>"1-777-777-7777"},
"codes"=>{"code_name"=>"S-5463",
"status"=>"Active",
"description"=>"Transition from sch to mkt"},
"codelines"=>{"units_alloc"=>"80.00"}},
"commit"=>"Save"}
更新1
我将contract_controller的新动作更改为:
def new
@contract = Contract.new
通过契约构建代码行对象,然后通过代码行对象构建代码
codelines = @contract.codelines.build
codelines.codes.build
通过合同构建clientlines对象,然后通过clientlines对象构建客户端
clientlines = @contract.clientlines.build
clientlines.clients.build
end
我还通过添加accepts_nested_attributes_for:clientlines,:codelines以及添加attr_accessor行来更改我的合约模型。
class Contract < ActiveRecord::Base
has_many :clientlines
has_many :codelines
has_many :clients, :through => :clientlines
has_many :codes, :through => :codelines
accepts_nested_attributes_for :clients
accepts_nested_attributes_for :codes
accepts_nested_attributes_for :clientlines
accepts_nested_attributes_for :codelines
attr_accessor :codes, :clients, :clientlines, :codelines
end
我现在在我的参数中有关联名称的nested_attribute_writers,但现在我的错误已更改为:
NoMethodError in ContractsController#new
undefined method `build' for nil:NilClass
现在的问题是,&#34;让attr_accessor引用所有关联是否正确?&#34; 我的另一个问题是,&#34;我是否必须使用form_helper为客户端,代码和代码行创建记录?&#34;我问这个的原因是,尽管我在contract_controller中有构建操作,但似乎它仍然是零。 如果对第二个问题的回答是肯定的,你可以指导我一些资源来指导我建立一个form_helper吗?我正在检查RailsGuides。
感谢。
更新2
我一直在圈子里,我将contract_controller的新动作改为:
def new
@contract = Contract.new
@contract.codes.build
@contract.clients.build
end
我还将合同模型改回:
class Contract < ActiveRecord::Base
has_many :clientlines
has_many :codelines
has_many :clients, :through => :clientlines
has_many :codes, :through => :codelines
accepts_nested_attributes_for :clients
accepts_nested_attributes_for :codes
attr_accessible :clients_attributes, :codes_attributes etc
end
最后,我删除了我的视图partial,_ fields.html.haml中与代码行相关的部分,即:
= f.fields_for :codelines do |ff| and the next four lines
现在我的params有必要的&#34; clients_attributes&#34;和&#34; codes_attributes&#34;结果表格保存到适当的表格中。我还有一些问题,即代码行中的额外属性,&#39; units_alloc&#39;和其他一些事情,但事情看起来更好。
答案 0 :(得分:2)
好的,所以问题在于表单的设置方式。
您的contract
模型可以接受clientlines
的嵌套属性,但是,您尝试接受clients
,code
的嵌套属性。
为此,您需要按照以下方式设置Contract
模型:
class Contract < AR::Base
has_many :clientlines
has_many :codelines
has_many :clients, :through => :clientlines
has_many :codes, :through => :codelines
accepts_nested_attributes_for :codes
accepts_nested_attributes_for :clients
end
我想我理解你的困惑,因为ClientLines
是codes
和clients
的所有者,你应该接受嵌套属性的关系,但这是不正确的。
使用has_many :codes, :through => :clientlines
后,您已在Contract
和Code
之间设置了第一类关联,因此,如果您想在codes
中创建新的contract
}表单,然后您需要在accepts_nested_attributes_for :codes
模型中说Contract
。
希望这有帮助。
因此,关于您上次发布参数的问题,问题是:codes
和:clients
。如果您的accepts_nested_attributes_for :codes
模型中有accepts_nested_attributes_for :clients
和Contract
代码,那么这应该可以正常使用。
问题是,为了正确构建客户端或代码,您还需要构建其父对象。所以你的控制器看起来应该更像这样:
class ContractsController < ApplicationController
def new
@contract = Contract.new
#Build the codelines object throught the contract, then build the codes through the codelines object
codelines = @contract.codelines.build
codelines.build_code
# Do the same for the clients
clientlines = @contract.clientlines.build
clientlines.build_client
end
现在,如果您已正确完成此操作,而不是在:clients
中看到:codes
或params
,则应该看到:clients_attributes
或:codes_attributes
。< / p>
我真的认为应该这样做。
答案 1 :(得分:0)
第一个答案是一个很大的帮助,但它没有让我一直到解决方案。 我找到了一个解决方案,它确实将我带到了这个网站的最后debugging nested_forms。
这是你读过的第九个项目,如果你正在使用has_many:通过关联,那么你需要将你的nested_form基于连接模型或接近它的东西。
我通过在这里和那里重构一些代码来快速运行测试,现在我有一个可行的嵌套表单,它向控制器提供正确的参数,然后控制器正确地处理它,我的代码行表现在只有一个记录。