Ruby on rails Rails 4无法访问嵌套形式的散列(对于nil:NilClass,未定义方法“[]'”)
我构建了一个相当复杂的表单,它创建了一个包含许多不动产的处方。我在视图中使用此语法:Ruby on rails Rails 4无法访问嵌套形式的散列(对于nil:NilClass,未定义方法“[]'”),ruby-on-rails,ruby,hash,nested-forms,params,Ruby On Rails,Ruby,Hash,Nested Forms,Params,我构建了一个相当复杂的表单,它创建了一个包含许多不动产的处方。我在视图中使用此语法: - provide(:title, 'Create prescription') %h1 Add medicines to prescription .row .span6.offset3 = form_for @prescription do |f| = render 'shared/error_prescription_messages' %p = f.h
- provide(:title, 'Create prescription')
%h1 Add medicines to prescription
.row
.span6.offset3
= form_for @prescription do |f|
= render 'shared/error_prescription_messages'
%p
= f.hidden_field :patient_id, :value => params[:patient_id]
= f.hidden_field :user_id, :value => current_user.id
= f.fields_for :relations do |builder|
= render 'child_form', :f => builder
%p= f.submit "Submit"
chlid_表单非常简单:
- it=f.options[:child_index].to_i
- n= it.to_s
%h2
= "Medicine ##{it+1}"
= f.hidden_field :medicine_id, :id => "my_medicine_id#{it}"
- if params[:prescription].nil? || params[:prescription][:relations_attributes][n.to_sym][:medicine_name].nil?
= f.autocomplete_field :medicine_name, autocomplete_medicine_name_relations_path, :id_element => "#my_medicine_id#{it}"
- else
= f.autocomplete_field :medicine_name, autocomplete_medicine_name_relations_path, :id_element => "#my_medicine_id#{it}", :value => params[:prescription][:relations_attributes][n.to_sym][:medicine_name]
= f.label :amount, "Amount of medicine boxes"
= f.number_field :amount, :value => 1
= f.label :daily
= f.number_field :daily, :value => 1
= f.label :period_in_days, "Duration of treatment (in days)"
= f.number_field :period_in_days, :value => 1
如你所见,我正在使用f.options[:child\u index]
来获取child(0,1,2…)的索引,因为我用这个特殊的表单生成了多个项。然后,我将其放入变量it
,并成功地在:id_元素=>“#我的药物#id#{it}”
中使用它,它工作得非常好(创建我的药物_id0,我的药物_id1…),尽管它在这行中不起作用:
:value=>参数[:处方][:关系属性][n.到符号][:药物名称]
其中n
就是n=it.to\u s
我觉得控制器有问题,但如果我把这行改成什么
:value=>params[:处方][:关系属性]**[:“0']**[:medicine\u name]
或0到4之间的任何其他整数一切都很好,但我需要在这一个中进行动态更改。所以我得到了它确实有效的证据,因为它在这里生成整数fine“#我的药#我的id#{it}”
,但在哈希中不起作用!当我从params打印整个散列时,我得到:
{patient\u id=>“7”、“user\u id=>“1”、“relations\u attributes”=>{medicine\u id=>“13490”、“medicine\u name”=>“Locacid 500 mcg/g(0,05%)(1大号30克)”、“amount”=>“0”、“daily”=>“1”、“period\u in\u in\u days”=>“1”、“medicine\u id”=>、“medicine\u name”=>、“amount”、“amount”=>“1”、“daily”=>“period”、“period”=>“period\u”=>“period”=>“2”,“药品名称”、“金额”、“1”、“每日”、“期间日数”、“药品名称”、“金额日数”、“1”、“期间日数”、“药品名称”、“金额日数”、“1”、“期间日数”
所以要得到我需要的值,很明显
参数[:处方][:关系\u属性][某种类型的INETEGER][:药物\u名称]
应该可以工作,但不能
控制器代码:
class PrescriptionsController < ApplicationController
before_action :signed_in_user
before_action :doctor_user, only: [:new, :create]
before_action :pharmacist_user, only: [:update]
def new
@prescription =Prescription.new
5.times { @prescription.relations.build }
end
def create
@prescription = Prescription.new(new_prescription_params)
if @prescription.save
flash[:success] = "Prescription created."
redirect_to @prescription
else
5.times { @prescription.relations.build }
render 'new', :prescription => params[:prescription]
end
end
def show
@prescription = Prescription.find(params[:id])
@medicines = @prescription.medicines.paginate(page: params[:page], :per_page => 10)
end
def update
@prescription = Prescription.find(params[:id])
@patient = Patient.find(params[:patient_id])
if !prescription_expired?(@prescription)
@prescription.realized = 1
if @prescription.save
flash[:success] = "Prescription realized."
redirect_to @patient
else
redirect_to root_url
end
else
flash[:notice] = "Can't realize, prescription expired."
redirect_to @patient
end
end
private
def new_prescription_params
params.require(:prescription).
permit(:patient_id, :user_id, relations_attributes: [:medicine_id, :medicine_name, :amount, :daily, :period_in_days])
end
def doctor_user
redirect_to(root_url) unless current_user.function == "doctor"
end
def pharmacist_user
redirect_to(root_url) unless current_user.function == "pharmacist"
end
def prescription_expired?(presc)
presc.created_at < 1.month.ago
end
def signed_in_user
unless signed_in?
store_location
flash[:notice] = "Please log in."
redirect_to login_url
end
end
类处方控制器params[:处方]
结束
结束
def秀
@处方=处方。查找(参数[:id])
@medicines=@prescription.medicines.paginate(第页:参数[:第页],:每页=>10)
结束
def更新
@处方=处方。查找(参数[:id])
@patient=patient.find(参数[:patient\u id])
如果!处方已过期?(@处方)
@1.1=1
如果@prescription.save
flash[:success]=“处方已实现。”
将_重定向到@patient
其他的
将\u重定向到根\u url
结束
其他的
flash[:notice]=“无法实现,处方过期。”
将_重定向到@patient
结束
结束
私有的
def新处方参数
参数要求(:处方)。
许可证(:患者id,:用户id,关系属性:[:药物id,:药物名称,:金额,:每日,:期间(以天为单位)])
结束
def医生\用户
除非当前用户函数==“医生”,否则重定向到(根url)
结束
def药剂师\用户
将\重定向到(根\ url),除非当前\用户。函数==“pharmacist”
结束
def处方已过期?(PREC)
在<1.1个月前创建的PREC.U
结束
def已签名用户
除非你签了名?
门店位置
flash[:notice]=“请登录。”
将\u重定向到登录\u url
结束
结束
结束
我没有主意了,所以我问你们是否有人可以帮忙。谢谢。在您的视图中使用参数没有任何意义,因为您已经将这些参数指定给了您的模型。另外,当您渲染新动作时,这些参数并不存在,因为还没有向服务器发送任何内容。只需从输入中删除所有值即可美国
您的局部视图应该如下所示:
- it=f.options[:child_index].to_i
- n= it.to_s
%h2
= "Medicine ##{it+1}"
= f.hidden_field :medicine_id, :id => "my_medicine_id#{it}"
= f.autocomplete_field :medicine_name, autocomplete_medicine_name_relations_path
= f.label :amount, "Amount of medicine boxes"
= f.number_field :amount
= f.label :daily
= f.number_field :daily
= f.label :period_in_days, "Duration of treatment (in days)"
= f.number_field :period_in_days
如果您希望字段具有默认值,请在数据库中设置默认值。rails的做法似乎不符合此要求。为什么要将表单元素与模型绑定,然后覆盖此属性值?这应该在控制器中完成。请使用控制器代码更新您的问题,以便我们将其清除。我不确定为什么你要做[n.to_sym]
…我认为[n]
会起作用,不是吗?它不是散列转储中的一个符号。不要写任何个人的东西。读到有人声称他们感到沮丧是令人沮丧的。这与问题无关。而且,初学者通常会写“奇怪/奇怪的行为”之类的词,但在大多数情况下,语言/框架并没有什么奇怪或奇怪的地方,很可能是那些声称奇怪的人的想法。@SteveTurczyn[n]不起作用,我尝试了许多变体,如:“#{n}”和加载不同的内容。@BroiSatse我添加了控制器代码。@Herwish-默认值是一个模型,而不是控制器和视图。TBH,我从未发现value param有任何用途。正如我在回答的底部所提到的,在数据库列上设置一个默认值,或者在初始化后添加,钩住你的模型。而不是@prescription=prescription.new
do@prescription=patient.find(parms[:patient\u id])。prescriptions.build
@Herwish-也去掉那里的值。Do@prescription=patient.find(parms[:patient\u id]).prescriptions.build(user\u id:current\u user)
是