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

Rails中如何获取刚通过form_with创建的模型ID用于跨控制器操作

Rails新手问题:获取刚创建的FeatureUse ID用于删除按钮

我是Rails新手,可能操作方式有误。在show.html.erb中遍历@feature,渲染创建FeatureUse的表单,现在需要实现删除按钮,但不清楚如何获取尚未创建的FeatureUse的ID传入feature_use_path。

现有代码

show.html.erb

<% @feature.each do |p| %>
    <br>
    <h1><%= p.name %></h1>
       <%= p.unit_price %>
    <%= render partial: "shared/featureuse_form", locals: {feat_use: @feat_use , feature: p} %>
    <%= button_to'Change' , feature_use_path(1) , :class => 'btn btn-primary'  ,method: :delete %>
<% end %>

_featureuse_form.html.erb

<%= form_with model: feat_use do |f| %>
    <%= f.number_field :total_units ,value: feature.max_unit_limit  %>
    <%= f.hidden_field :feature_id, value: feature.id %>
    <%= f.hidden_field :usage_id, value: current_user.usage.id %>
    <%= f.submit "confirm", id: "button"%> 
<% end %>

控制器代码

class PlansController < ApplicationController
    before_action :authenticate_user!
    def index
        @plan = Plan.all
    end
    def show
        @plan = Plan.find(params[:id])
        @feature = @plan.features
        @feat_use = FeatureUse.new
    end
end

class FeatureUsesController < ApplicationController
  def create
        feature_use = FeatureUse.new(feature_use_params)
        feature_use.total_units = params[:feature_use][:total_units]
        feature_use.feature_id = params[:feature_use][:feature_id]
        user = current_user.usage
        feature_use.usage_id = user.id
        feature_use.save
            
  end
end

解决方案

核心逻辑:删除按钮只能对应已创建的FeatureUse记录,未创建的记录没有ID无法执行删除操作。我们需要先关联当前用户已有的FeatureUse和对应Feature,再动态显示删除按钮。

1. 修改PlansController的show方法

加载当前用户已关联的FeatureUse,与Plan的Features配对:

class PlansController < ApplicationController
  before_action :authenticate_user!

  def index
    @plan = Plan.all
  end

  def show
    @plan = Plan.find(params[:id])
    @features = @plan.features # 变量名改为复数更符合Rails规范
    # 按feature_id分组,快速匹配用户已有的FeatureUse
    user_feature_uses = current_user.usage.feature_uses.index_by(&:feature_id)
    # 为每个Feature匹配对应的FeatureUse:已有记录或新建实例
    @feature_use_pairs = @features.map do |feature|
      [feature, user_feature_uses[feature.id] || FeatureUse.new]
    end
  end
end

2. 更新show.html.erb模板

遍历配对后的Feature和FeatureUse,仅对已持久化的记录显示删除按钮:

<% @feature_use_pairs.each do |feature, feat_use| %>
  <br>
  <h1><%= feature.name %></h1>
  <%= feature.unit_price %>
  <%= render partial: "shared/featureuse_form", locals: {feat_use: feat_use, feature: feature} %>
  <%# 只有已创建的记录才显示删除按钮 %>
  <% if feat_use.persisted? %>
    <%= button_to 'Delete', feature_use_path(feat_use), class: 'btn btn-primary', method: :delete %>
  <% end %>
<% end %>

3. 优化_featureuse_form.html.erb

让表单自动适配新建/更新场景,按钮文字动态调整:

<%= form_with model: feat_use do |f| %>
  <%# 如果是已存在的记录,显示已保存的total_units,否则用feature的默认值 %>
  <%= f.number_field :total_units, value: feat_use.total_units || feature.max_unit_limit %>
  <%= f.hidden_field :feature_id, value: feature.id %>
  <%= f.hidden_field :usage_id, value: current_user.usage.id %>
  <%# 新建时显示Confirm,更新时显示Update %>
  <%= f.submit feat_use.persisted? ? "Update" : "Confirm", id: "button" %>
<% end %>

4. 完善FeatureUsesController

添加update、destroy方法,规范强参数写法:

class FeatureUsesController < ApplicationController
  before_action :authenticate_user!

  def create
    @feature_use = current_user.usage.feature_uses.new(feature_use_params)
    if @feature_use.save
      # 保存成功后跳转回Plan的show页面
      redirect_to plan_path(@feature_use.feature.plan)
    else
      # 保存失败时回到原页面,保留错误状态
      @plan = @feature_use.feature.plan
      @features = @plan.features
      user_feature_uses = current_user.usage.feature_uses.index_by(&:feature_id)
      @feature_use_pairs = @features.map do |feature|
        [feature, feature.id == @feature_use.feature_id ? @feature_use : user_feature_uses[feature.id] || FeatureUse.new]
      end
      render 'plans/show'
    end
  end

  def update
    @feature_use = current_user.usage.feature_uses.find(params[:id])
    if @feature_use.update(feature_use_params)
      redirect_to plan_path(@feature_use.feature.plan)
    else
      @plan = @feature_use.feature.plan
      @features = @plan.features
      user_feature_uses = current_user.usage.feature_uses.index_by(&:feature_id)
      @feature_use_pairs = @features.map do |feature|
        [feature, feature.id == @feature_use.feature_id ? @feature_use : user_feature_uses[feature.id] || FeatureUse.new]
      end
      render 'plans/show'
    end
  end

  def destroy
    @feature_use = current_user.usage.feature_uses.find(params[:id])
    @feature_use.destroy
    redirect_to plan_path(@feature_use.feature.plan), notice: 'Feature use was deleted successfully.'
  end

  private

  def feature_use_params
    params.require(:feature_use).permit(:total_units, :feature_id, :usage_id)
  end
end

5. 确认路由配置

确保routes.rb中包含FeatureUses的资源路由:

Rails.application.routes.draw do
  # 其他路由...
  resources :feature_uses
  resources :plans
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 16:06:27