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

Roles#new出现NameError:未定义局部变量或方法`permissions'

角色创建页面权限复选框错误修复方案

问题背景

正在开发角色与权限功能,目标是在角色创建页面添加权限复选框,让管理员创建角色时勾选权限并存储到role_permission关联表中,要求新增权限能同步显示在页面,但目前页面显示复选框时出现错误。

相关代码

Role控制器

def new
 @role = Role.new
 @role.company_id = params[:company_id]
 @permission = Permission.all
end

def create
 @role = Role.new(role_params)
 @company_id = Company.find(params[:role][:company_id])
 @permission_id = Permission.all
 if @role.save
   flash[:success] = "Succesful create!"
   redirect_to @role
 else
   render 'new'
 end
end

private

def role_params
  params.require(:role).permit(:name, :company_id)
end

角色创建视图(new.html.erb)

<% provide(:title, "Create Roles") %>
<h1>Create Role</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
   <%= form_with(model: @role, local: true) do |f| %>
   <%= permissions.each do |permission|%>
   <%= render 'shared/error_messages', object: f.object %>

  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>

  <%= f.label :permission_id %>
  <%= f.check_box_tag 'permission_ids[]', permission.id, false%>

  <%= f.hidden_field :company_id , value: 2%>

   <%= f.submit "Create Role", class: "btn btn-primary" %>
   <% end %>
 <% end %>
</div>

错误信息

  • 网站错误:未定义局部变量或方法 `permissions'
  • 控制台错误:ActionView::Template::Error (undefined local variable or method `permissions' for #<#Class:0x00007f9b8c16d0c8:0x00007f9b8e0a2108>)
  • 更新后错误:表单元素重复渲染(每个权限都生成一次名称输入框、提交按钮等)

错误修复步骤

1. 修正视图变量名错误

控制器中定义的实例变量是@permission,但视图里误用了permissions,同时each循环前的<%=会导致页面输出集合对象,需调整:

<% @permission.each do |permission| %>

2. 调整表单结构,避免重复渲染核心元素

原代码把名称输入框、提交按钮等核心表单元素放在权限循环里,导致每个权限都生成一套重复控件。需将循环仅限定在复选框区域:

<% provide(:title, "Create Roles") %>
<h1>Create Role</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
   <%= form_with(model: @role, local: true) do |f| %>
     <%= render 'shared/error_messages', object: f.object %>

     <%= f.label :name %>
     <%= f.text_field :name, class: 'form-control' %>

     <!-- 权限复选框区域 -->
     <h3>选择权限</h3>
     <% @permission.each do |permission|%>
       <div class="checkbox">
         <%= check_box_tag 'role[permission_ids][]', permission.id, @role.permission_ids.include?(permission.id) %>
         <%= label_tag "role_permission_ids_#{permission.id}", permission.name %>
       </div>
     <% end %>

     <%= f.hidden_field :company_id , value: 2%>

     <%= f.submit "Create Role", class: "btn btn-primary" %>
   <% end %>
 </div>
</div>

3. 更新控制器参数白名单,接收权限ID数组

要让后台能接收勾选的权限ID数组,需在role_params中添加permission_ids: []:

private

def role_params
  params.require(:role).permit(:name, :company_id, permission_ids: [])
end

4. 确保模型关联关系正确

在Role模型中定义与Permission的多对多关联:

class Role < ApplicationRecord
  has_many :role_permissions
  has_many :permissions, through: :role_permissions
end

在Permission模型中定义反向关联:

class Permission < ApplicationRecord
  has_many :role_permissions
  has_many :roles, through: :role_permissions
end

5. 优化创建动作逻辑

删除无意义的@company_id代码,同时在渲染错误页面时重新加载权限列表:

def create
  @role = Role.new(role_params)
  if @role.save
    flash[:success] = "角色创建成功!"
    redirect_to @role
  else
    @permission = Permission.all # 渲染new视图时重新加载权限
    render 'new'
  end
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 19:10:34