Rails角色 - 用户管理:has_many通过控制器设置

问题描述 投票:0回答:1

我正在尝试修复我的用户角色分配问题。我有一个User和一个Role模型,我添加了一个RoleAssignment模型来设置has_many。目标是为用户分配许多角色,角色可以有许多用户分配。

它在我在rails控制台中测试时有效,但到目前为止我的控制器内没有。我认为我的params部分存在问题。

在我使用的控制器中

params.require(:user).permit(:name, :email, :password,  :password_confirmation, role_assignments_attributes: [:role, :id])

但更新不起作用

# app/models/role.rb
class Role < ApplicationRecord
    has_many :role_assignments
    has_many :users, :through => :role_assignments
    validates :name, :presence => true
    validates :description, :presence => true
end

# app/models/role_assignment.rb
class RoleAssignment < ApplicationRecord
    belongs_to :user
    belongs_to :role
end

# app/models/user.rb
class User < ApplicationRecord
    has_many :role_assignments
    has_many :roles, :through => :role_assignments
    accepts_nested_attributes_for :role_assignments

    def has_role?(role_sym)
        roles.any? { |r| r.name.underscore.to_sym == role_sym }
    end
end

UsersController:

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]

  def edit
  end

  def update
    respond_to do |format|
      if @user.update(user_params) 
        format.html { redirect_to edit_user_path(@user.public_uid), 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
  end

  private
    def user_params
      #params.fetch(:user, {})
      params.require(:user).permit(:name, :email, :password,  :password_confirmation, role_assignments_attributes: [:role, :id])
    end
end

用户/编辑视图:

<% for role in Role.all %>
<div>
  <%= check_box_tag "user[role_assignments_attributes][]", role.id, @user.roles.include?(role) %>
  <%=h role.name %>
</div>
<% end %>

在这里我在rails console中尝试了它(成功)

> 2.4.1 :003 > u.roles << Role.find([1,2])   Role Load (0.6ms)  SELECT "roles".* FROM "roles" WHERE "roles"."id" IN (?, ?)  [["id", 1],
> ["id", 2]]    (0.1ms)  begin transaction   RoleAssignment Create
> (0.4ms)  INSERT INTO "role_assignments" ("user_id", "role_id",
> "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["user_id", 1],
> ["role_id", 1], ["created_at", "2019-02-27 21:51:47.918815"],
> ["updated_at", "2019-02-27 21:51:47.918815"]]   RoleAssignment Create
> (0.2ms)  INSERT INTO "role_assignments" ("user_id", "role_id",
> "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["user_id", 1],
> ["role_id", 2], ["created_at", "2019-02-27 21:51:47.921373"],
> ["updated_at", "2019-02-27 21:51:47.921373"]]    (4.2ms)  commit
> transaction   Role Load (0.2ms)  SELECT  "roles".* FROM "roles" INNER
> JOIN "role_assignments" ON "roles"."id" = "role_assignments"."role_id"
> WHERE "role_assignments"."user_id" = ? LIMIT ?  [["user_id", 1],
> ["LIMIT", 11]]  => #<ActiveRecord::Associations::CollectionProxy
> [#<Role id: 1, name: "Administrator", created_at: "2019-02-27
> 18:26:04", updated_at: "2019-02-27 18:35:26", description:
> "Administrator">, #<Role id: 2, name: "Support", created_at:
> "2019-02-27 18:26:26", updated_at: "2019-02-27 18:35:40", description:
> "Support">]> 
> 2.4.1 :005 > u.save
ruby-on-rails roles has-many
1个回答
1
投票

它比你想做的更简单。不需要nested_attributes,只需使用role_ids方法。从用户模型中删除accepts_nested_attributes_for行并更改强参数并形成一点

def user_params
  params.require(:user).permit(:name, :email, :password,  :password_confirmation, role_ids: [])
end

# I suppose you have some kind of @user form in edit view
<% form_for @user do |f| %>
  <%= f.collection_check_boxes(:role_ids, Role.all, :id, :name) %>
<% end %>
© www.soinside.com 2019 - 2024. All rights reserved.