我正在渲染这样的形式:
= f.fields_for :files do |files_form|
= render('file_form', f: files_form)
在_file_form.html.slim中我有这样的代码:
- id = f.object.id
- file= f.object.files.first
li.panel.panel-default
.panel-heading role="tab" id="heading"
a.file-heading data-toggle="collapse" data-parent="#files" href="#collapse#{id}"
div.clearfix role="button"
span = f.object.name
.panel-collapse.collapse-in id="collapse#{id}" role="tabpanel"
.panel-body
.clearfix = link_to(t('shared.destroy'), '#', class:'btn btn-warning btn-sm discard-file pull-right')
.form-group
= f.label(:name, t('activerecord.attributes.file.name'))
= f.text_field(:name, class: 'form-control')
= f.label(file.id) //my problem
一切正常,直到我尝试使用文件ID获取标签。
错误讯息:未定义的方法`id'为零:NilClass
看起来似乎没有初始化,但实际上,当我在调试器中使用 file.id 进行检查之前,它已初始化并且我可以轻松地检查它的值。
当我使用:id 而不是 file.id 时,一切正常。为什么呢?
当我尝试从中检索id(或任何其他数据)时,为什么file是nil类?
答案 0 :(得分:0)
您的files
收藏品为空。因此,当您执行file = f.object.files.first
时,file
本地变量将被分配nil
。
当您尝试将其作为具有名称id
的属性的对象进行访问时,它会被抛出。
根据您的使用情况,如果集合中没有元素或使用技术处理nil
值,您可以保释:
f.label(file.try(:id))
或
f.label(file&.id) # Ruby 2.3.0 and up
或
f.label(file.id rescue 'placeholder label')
更新
要使fields_for
起作用,父模型需要接受您使用的关联对象的属性。确保在父模型中具有此功能:
has_many :files
accepts_nested_attributes_for :files
除非后面的行存在,否则表单对象将为nil,这可能是您观察行为的原因。