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

Rails6报错:form_for首个参数不可为nil/空,无法渲染编辑表单

问题详情

点击用户列表中下拉菜单的edit链接时,页面抛出模板错误:

ActionView::Template::Error (First argument in form cannot contain nil or be empty):
1: = form_for [:admin, @tenant, @user] do |f|

触发错误的请求信息:

  • 请求URL:http://localhost:3000/admin/tenants/2/users/3/edit
  • 请求方法:GET
  • 作用:渲染用户编辑表单

相关代码

Admin::UsersController 部分代码

class Admin::UsersController < Admin::BaseController
  before_action :set_tenant

  def edit
  end

  def update
    respond_to do |format|
      if @user.update(user_params)
        format.html { redirect_to [:admin, @tenant, @user], notice: 'User was successfully updated.' }
        format.json { render :show, status: :ok, location: @user }
      else
        format.html { render :edit }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  private
  def set_tenant
    @tenant = Tenant.find(params[:tenant_id])
  end
  
  def set_user 
    @user = User.find(params[:id])
  end
  
  def user_params
    params.require(:user).permit(:email, :password, :password_confirmation, :tenant_id, :unit_id)
  end
end

用户列表视图(app/views/admin/users/index.html.haml)

= render(partial: 'admin/tenants/sublinks')
%h5.section-heading.mt20
  Listing Users
  .flex
  = link_to 'New User', new_admin_tenant_user_path(@tenant), class: "waves-effect waves-light btn btn-small primary"

%table
  %thead
    %tr
      %th Email
      %th Default Unit
      %th Created at
      %th 
      %th 
      -# %th Delete User

  %tbody
    - @tenant.users.each do |user|
      %tr
        %td= user.email
        %td= user.unit.name
        %td= user.created_at

        -# %td= link_to 'Delete', admin_tenant_user_path(@tenant, user.id), class: "waves-effect waves-red btn btn-small primary", method: :delete
        %td
          %a.dropdown-trigger.btn.waves-effect.waves-teal.btn-flat.right{"data-target" => "client_dropdown#{user.id}", :href => "#"}
            %i.material-icons.right>expand_more
            More
          %ul.dropdown-content{id: "client_dropdown#{user.id}"}
            %li
              = link_to 'Edit', edit_admin_tenant_user_path(@tenant, user)
            %li
              = link_to 'Destroy', [:admin, @tenant, user], method: :delete, data: { confirm: 'Are you sure?' }

路由信息

admin_tenant_users GET        /admin/tenants/:tenant_id/users(.:format)                                                     admin/users#index
                                              POST       /admin/tenants/:tenant_id/users(.:format)                                                     admin/users#create
                        new_admin_tenant_user GET        /admin/tenants/:tenant_id/users/new(.:format)                                                 admin/users#new
                       edit_admin_tenant_user GET        /admin/tenants/:tenant_id/users/:id/edit(.:format)                                            admin/users#edit
                            admin_tenant_user GET        /admin/tenants/:tenant_id/users/:id(.:format)                                                 admin/users#show
                                              PATCH      /admin/tenants/:tenant_id/users/:id(.:format)                                                 admin/users#update
                                              PUT        /admin/tenants/:tenant_id/users/:id(.:format)                                                 admin/users#update
                                              DELETE     /admin/tenants/:tenant_id/users/:id(.:format)                                                 admin/users#destroy
解决方案

错误根源是edit和update动作中,@user变量未被初始化。控制器中已经定义了set_user方法用于查找用户,但没有将其设置为前置回调,导致渲染表单时@user为nil,触发form_for参数错误。

修改Admin::UsersController,添加set_user的前置回调:

class Admin::UsersController < Admin::BaseController
  before_action :set_tenant
  # 添加这行,指定在edit和update动作前执行set_user
  before_action :set_user, only: [:edit, :update]

  def edit
  end

  def update
    respond_to do |format|
      if @user.update(user_params)
        format.html { redirect_to [:admin, @tenant, @user], notice: 'User was successfully updated.' }
        format.json { render :show, status: :ok, location: @user }
      else
        format.html { render :edit }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end

  # 私有方法部分保持不变
  private
  def set_tenant
    @tenant = Tenant.find(params[:tenant_id])
  end
  
  def set_user 
    @user = User.find(params[:id])
  end
  
  def user_params
    params.require(:user).permit(:email, :password, :password_confirmation, :tenant_id, :unit_id)
  end
end

修改后,edit和update动作执行前会自动调用set_user方法,初始化@user变量,表单就能正常渲染,编辑操作也能正常完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:55:18