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
相关产品推荐
相关产品推荐

