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

Rails+Stimulus环境下Tom-select创建记录后下拉选项不更新

问题描述

在Rails应用中结合Stimulus使用tom-select,目标是动态创建Vendor模型记录后,能在Trx模型的下拉菜单中选择该记录。目前已成功通过fetch请求创建记录,但下拉菜单并未更新。参考SupeRails #17视频12:14处的内容,其网络标签页显示两个请求(一个fetch和一个xhr),但我的应用仅显示一个状态码为200的fetch请求。

请问如何操作才能让新创建的记录显示在下拉菜单中?

相关代码

Stimulus控制器(vendor_select_controller.js)

settings = {
      plugins: ['clear_button'],
      selectOnTab: true,
      valueField: 'id',
      labelField: 'name',
      searchField: 'name',
      sortField: { field: "name", direction: "asc" },
      create: function (input, callback) {
        const data = { name: input }
        const token = document.getElementsByName("csrf-token")[0].content;
        fetch('/vendors', {
          body: JSON.stringify(data),
          method: 'POST',
          dataType: 'script',
          credentials: 'include',
          headers: {
            "X-CSRF-Token": token,
            "Content-Type": "application/json",
            "Accept": "application/json"
          },
        }).then((response) => { return response.json() })
          .then((data) => { callback({ value: data.id, text: data.name }) })
      },
      onItemAdd: function () {
        this.setTextboxValue('');
        this.refreshOptions();
      },
    }

VendorsController代码

class VendorsController < ApplicationController
...
  def create
    @vendor = Vendor.new(vendor_params)

    respond_to do |format|
      if @vendor.save
        format.html { redirect_to vendors_path }
        format.json { render json: @vendor }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @vendor.errors, status: :unprocessable_entity }
      end
    end
  end

Trx表单中的Vendor collection_select字段

<%= f.collection_select :vendor_id, Vendor.all, :id, :name, {:prompt => "Select Vendor"},
  {class: "w-full", data: { controller: "vendor-select" } } %>

控制台日志输出

Started POST "/vendors" for 127.0.0.1 at 2023-04-14 16:18:43 -0700
Processing by VendorsController#create as JSON
  Parameters: {"name"=>"Pines8", "vendor"=>{"name"=>"Pines8"}}
  TRANSACTION (0.1ms)  begin transaction
  ↳ app/controllers/vendors_controller.rb:11:in `block in create'
  Vendor Create (0.3ms)  INSERT INTO "vendors" ("name", "created_at", "updated_at") VALUES (?, ?, ?)  [["name", "Pines8"], ["created_at", "2023-04-14 23:18:43.634246"], ["updated_at", "2023-04-14 23:18:43.634246"]]
  ↳ app/controllers/vendors_controller.rb:11:in `block in create'
  TRANSACTION (6.2ms)  commit transaction
  ↳ app/controllers/vendors_controller.rb:11:in `block in create'
Completed 200 OK in 12ms (Views: 0.3ms | ActiveRecord: 6.6ms | Allocations: 2695)
解决方案

核心问题是tom-select的create回调参数格式与配置不匹配,导致新记录无法被正确识别并添加到下拉列表,按以下步骤修改即可解决:

  1. 修正回调参数格式:
    你设置了valueField: 'id'和labelField: 'name',但原代码传给callback的是{ value: data.id, text: data.name },这和tom-select的字段映射不对应。需要改成和配置字段一致的键名,同时手动刷新选项确保生效:

    create: function (input, callback) {
      const data = { name: input }
      const token = document.getElementsByName("csrf-token")[0].content;
      fetch('/vendors', {
        body: JSON.stringify(data),
        method: 'POST',
        credentials: 'include',
        headers: {
          "X-CSRF-Token": token,
          "Content-Type": "application/json",
          "Accept": "application/json"
        },
      })
      .then(response => response.json())
      .then(data => {
        callback({ id: data.id, name: data.name });
        this.refreshOptions();
      })
      .catch(error => console.error('创建供应商失败:', error));
    }
    
  2. 移除无效参数:
    Fetch API不支持jQuery的dataType: 'script'参数,直接删掉即可。

  3. 统一参数格式(可选但推荐):
    日志显示请求参数同时包含顶级name和嵌套的vendor[name],可以修改前端请求数据格式,更符合Rails约定:

    const data = { vendor: { name: input } }
    

    同时确保控制器的强参数设置正确:

    private
    def vendor_params
      params.require(:vendor).permit(:name)
    end
    

修改后,新创建的Vendor会被tom-select正确添加到下拉选项中,无需额外请求——视频中的两个请求是因为使用了Turbo Stream等其他方案,你的场景用tom-select原生回调即可解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:03:14