Rails 7使用vanilla-nested时出现link_to_add_nested未定义错误
Rails 7 用 vanilla-nested 实现动态嵌套字段报错解决
问题详情
跟着Rails 5旧课程用Cocoon做表单动态嵌套字段,因Cocoon久未更新切换到vanilla-nested,但两者在同一位置触发相同错误,排查方向锁定自身代码:
- 环境:esbuild构建工具,通过yarn安装cocoon、vanilla-nested;jQuery可正常用于Bootstrap,控制台
$ === jquery返回true;切换时已移除Cocoon导入标签 - 错误信息:
undefined method `link_to_add_nested' for #ActionView::Base:0x00000000011350 对应的代码行:'.freeze;@output_buffer.append=( link_to_add_nested(f, :technologies, 'Add Technology') );@output_buffer.safe_append=' 提示:Did you mean? link_to_next_page
- 涉及文件:
app/views/portfolios/_form.html.erb:调用link_to_add_nested方法app/models/portfolio.rb:定义has_many :technologies及accepts_nested_attributes_forapp/controllers/portfolios_controller.rb:参数许可包含technologies_attributesapp/javascript/application.js:已导入vanilla-nested
解决步骤
1. 手动添加视图辅助方法
vanilla-nested不会像Cocoon那样自动注入视图辅助方法,需在app/helpers/application_helper.rb中添加:
module ApplicationHelper def link_to_add_nested(form_association, association, text) new_object = form_association.object.send(association).klass.new id = "new_#{association}" fields = form_association.fields_for(association, new_object, child_index: id) do |builder| render(association.to_s.singularize + "_fields", f: builder) end link_to(text, '#', class: "add_nested_fields", data: {id: id, fields: fields.gsub("\n", "")}) end def link_to_remove_nested(form_association, text) form_association.hidden_field(:_destroy) + link_to(text, '#', class: "remove_nested_fields") end end
2. 检查嵌套字段局部模板
确保_technologies_fields.html.erb存在且内容正确,示例:
<div class="nested-fields"> <%= f.label :name %> <%= f.text_field :name %> <%= link_to_remove_nested(f, 'Remove Technology') %> </div>
3. 确认JavaScript初始化正确
在app/javascript/application.js中完成vanilla-nested的导入与初始化:
import VanillaNested from 'vanilla-nested' document.addEventListener('DOMContentLoaded', () => { VanillaNested.init() })
4. 验证模型与控制器配置
- 模型
app/models/portfolio.rb配置:
class Portfolio < ApplicationRecord has_many :technologies, dependent: :destroy accepts_nested_attributes_for :technologies, allow_destroy: true, reject_if: :all_blank end
- 控制器
app/controllers/portfolios_controller.rb参数许可:
def portfolio_params params.require(:portfolio).permit(:title, :description, technologies_attributes: [:id, :name, :_destroy]) end
5. 修正表单调用逻辑
确保app/views/portfolios/_form.html.erb中嵌套字段容器与辅助方法调用正确:
<div class="technologies-container"> <%= f.fields_for :technologies do |tech_form| %> <%= render 'technologies_fields', f: tech_form %> <% end %> <%= link_to_add_nested(f, :technologies, 'Add Technology') %> </div>
内容的提问来源于stack exchange,提问作者DebakeDSP94
相关产品推荐
相关产品推荐

