Rails 角色-用户-管理:has_many 通过控制器设置
Rails Role-User-Management: has_many through controller setup
我正在尝试解决我的用户角色分配问题。
我有一个 User 和一个 Role 模型,我添加了一个 RoleAssignment 模型来设置 has_many 通过。目标是为一个用户分配多个角色,一个角色可以分配多个用户。
当我在 rails 控制台中测试它时它可以工作,但到目前为止在我的控制器中没有。我认为我的参数部分有问题。
在我使用的控制器中
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
用户控制器:
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
users/edit 视图:
<% 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 控制台中尝试了(成功)
> 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
这比你想做的要简单。不需要 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 %>
我正在尝试解决我的用户角色分配问题。 我有一个 User 和一个 Role 模型,我添加了一个 RoleAssignment 模型来设置 has_many 通过。目标是为一个用户分配多个角色,一个角色可以分配多个用户。
当我在 rails 控制台中测试它时它可以工作,但到目前为止在我的控制器中没有。我认为我的参数部分有问题。
在我使用的控制器中
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
用户控制器:
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
users/edit 视图:
<% 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 控制台中尝试了(成功)
> 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
这比你想做的要简单。不需要 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 %>