You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 6中模型成功保存到数据库后如何执行JavaScript?

嘿,我太懂这种看似简单却卡壳的感觉了!作为Rails开发者,刚入门时也在AJAX提交这块踩过不少坑😅 先帮你解决当前代码没生效的问题,再聊聊两种方案的选择。

先搞定你当前的.js.erb不生效问题

你的controller代码是对的,问题大概率出在表单没有触发AJAX请求。Rails要识别JS响应,需要表单发送AJAX请求,而不是默认的HTML请求。

你要检查这几点:

  1. 表单是否开启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 %>
    
  2. UJS是否正确引入:
    打开app/javascript/packs/application.js,确认有这两行(Rails 6默认应该有,但万一被删掉了呢):
    import Rails from "@rails/ujs";
    Rails.start();
    
  3. 检查服务器日志:
    提交表单后,看终端里的服务器日志,如果看到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代码更规范。实现思路是:

  1. 修改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
    
  2. 在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));
      });
    });
    
  3. 在application.js里引入这个文件:
    import '../packs/job_form';
    

这种方式更符合现代前端的代码组织习惯,适合复杂的交互场景。

最后总结

如果只是当前的简单需求,先把.js.erb的AJAX问题解决就行,分分钟就能看到alert;如果之后有更复杂的JS逻辑,再慢慢迁移到Webpacker的方式。

内容的提问来源于stack exchange,提问作者Kris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 00:18:12