Rails 6中模型成功保存到数据库后如何执行JavaScript?
嘿,我太懂这种看似简单却卡壳的感觉了!作为Rails开发者,刚入门时也在AJAX提交这块踩过不少坑😅 先帮你解决当前代码没生效的问题,再聊聊两种方案的选择。
先搞定你当前的.js.erb不生效问题
你的controller代码是对的,问题大概率出在表单没有触发AJAX请求。Rails要识别JS响应,需要表单发送AJAX请求,而不是默认的HTML请求。
你要检查这几点:
- 表单是否开启AJAX:
Rails 6里用form_with的话,默认就是remote: true(自动发送AJAX),但如果你用的是旧的form_for,必须手动加remote: true:<%# 用form_with的情况(Rails 6推荐) %> <%= form_with(model: [current_user, @job]) do |form| %> # 你的表单字段 <%= form.submit "提交" %> <% end %> <%# 用form_for的情况 %> <%= form_for([current_user, @job], remote: true) do |form| %> # 你的表单字段 <%= form.submit "提交" %> <% end %> - UJS是否正确引入:
打开app/javascript/packs/application.js,确认有这两行(Rails 6默认应该有,但万一被删掉了呢):import Rails from "@rails/ujs"; Rails.start(); - 检查服务器日志:
提交表单后,看终端里的服务器日志,如果看到Rendering jobs/create.js.erb和Completed 200 OK,说明JS响应已经发送了,浏览器没弹alert可能是缓存问题,硬刷新一下页面试试。
再聊聊:用.js.erb还是Webpacker?
这两种方式没有绝对的“最佳”,要看你的需求场景:
场景1:简单逻辑(比如你的alert提示)→ 选.js.erb
这是最传统的Rails方式,优点是简单快速,不需要额外写复杂的JS逻辑,还能直接在JS里嵌入Ruby实例变量,比如:
// views/jobs/create.js.erb alert('Job <%= @job.id %> 创建成功啦!');
适合快速实现小功能,不用折腾前端打包逻辑。
场景2:复杂JS逻辑(比如需要操作DOM、调用API等)→ 选Webpacker
如果你的需求不止弹个alert,比如要动态更新页面列表、做动画效果,那用Webpacker组织JS代码更规范。实现思路是:
- 修改controller,返回JSON响应:
# controller/jobs_controller.rb def create @job = current_user.jobs.build(job_params) respond_to do |format| if @job.save format.html { redirect_to @job, notice: 'Success!' } format.json { render json: @job, status: :created } # 返回JSON else format.html { render :new } format.json { render json: @job.errors, status: :unprocessable_entity } end end end - 在Webpacker的JS文件里手动处理表单提交:
比如新建app/javascript/packs/job_form.js:document.addEventListener('DOMContentLoaded', () => { const jobForm = document.querySelector('#new_job'); if (!jobForm) return; jobForm.addEventListener('submit', (e) => { e.preventDefault(); // 阻止默认表单提交 const formData = new FormData(jobForm); const csrfToken = document.querySelector('meta[name="csrf-token"]').content; fetch(jobForm.action, { method: 'POST', body: formData, headers: { 'X-CSRF-Token': csrfToken } }) .then(res => { if (res.ok) return res.json(); throw new Error('保存失败'); }) .then(job => { alert(`Job ${job.id} 创建成功!`); // 这里可以加更多逻辑,比如把新job加到页面列表里 }) .catch(err => console.error(err)); }); }); - 在
application.js里引入这个文件:import '../packs/job_form';
这种方式更符合现代前端的代码组织习惯,适合复杂的交互场景。
最后总结
如果只是当前的简单需求,先把.js.erb的AJAX问题解决就行,分分钟就能看到alert;如果之后有更复杂的JS逻辑,再慢慢迁移到Webpacker的方式。
内容的提问来源于stack exchange,提问作者Kris
相关产品推荐
相关产品推荐

