Rails:如何通过模型中的 id 通过关系创建 has_many?
Rails: How to create has_many through relationships via the ids in the model?
我有三个模型:Customer
、Branch
和 CustomerBranch
在客户模型中:
has_many :customer_branches, inverse_of: :customer
has_many :branches, through: :customer_branches
在分支模型中:
has_many :customer_branches, inverse_of: :branch, dependent: :restrict_with_exception
has_many :customers, through: :customer_branches
在 CustomerBranch 模型中:
belongs_to :customer, inverse_of: :customer_branches
belongs_to :branch, inverse_of: :customer_branches
这是一个仅 api 的应用程序,我将获得一组分支 ID。现在我想 assign/remove 根据收到的 ID 从客户那里分支。
我有一个解决方案来处理这个问题,但我认为这不是最好的方法。这是我目前的解决方案:
attr_accessor :branches_ids
after_save :assign_branches
def assign_branches
return if self.branches_ids.nil?
old_branch_ids = self.branch_ids
remove_branch_ids = old_branch_ids - self.branches_ids
self.customer_branches.where(id: remove_branch_ids).delete_all if remove_branch_ids.present?
self.branches << Branch.where(id: self.branches_ids)
end
有没有更好的方法来处理这个问题?提前致谢!!
好了,回答问题。您可以直接在客户上设置 ID:
customer = Customer.find(1)
customer.branches_ids = [1,2,3]
Rails 将处理所有的添加和删除。
也适用于新客户:
customer = Customer.new
customer.name = "blabla"
customer.branches_ids = [1,2,3]
customer.save
您可以在控制器中执行此操作:
def assign_branches
customer = Customer.find(params[:id]) // however you gonna get custome whom we gonna assign branches
customer.branches = Branch.where(id: params[:branch_ids]) //however way you want to get ids
end
collection= 方法通过适当地添加和删除使集合仅包含提供的对象。修改持久化到database.For更多关于关联,可以通过:https://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference
在 Ubuntu 20.04[=29= 上构建 Rails 应用程序 时,我也有同样的担忧]
模型和控制器被命名为一个名为 Userbase
的模块:
用户模型
module Userbase
class User < ApplicationRecord
# Allow a user to have multiple permissions
has_many :user_permissions, class_name: Userbase::UserPermission, dependent: :nullify
has_many :permissions, through: :user_permissions
# Allow a user to have multiple roles
has_many :user_roles, class_name: Userbase::UserRole, dependent: :nullify
has_many :roles, through: :user_roles
end
end
榜样
module Userbase
class Role < ApplicationRecord
# Allow a role to have multiple users
has_many :user_roles, class_name: Userbase::UserRole, dependent: :nullify
has_many :users, through: :user_roles
# Allow a role to have multiple permissions
has_many :role_permissions, class_name: Userbase::Role, dependent: :nullify
has_many :permissions, through: :role_permissions
end
end
权限模型
module Userbase
class Permission < ApplicationRecord
# Allow a permission to have multiple users
has_many :user_permissions, class_name: Userbase::UserPermission, dependent: :nullify
has_many :users, through: :user_permissions
# Allow a permission to have multiple roles
has_many :role_permissions, class_name: Userbase::Role, dependent: :nullify
has_many :roles, through: :role_permissions
end
end
角色权限模型
module Userbase
class RolePermission < ApplicationRecord
belongs_to :role, class_name: Userbase::Role
belongs_to :permission, class_name: Userbase::Permission
end
end
用户权限模型
module Userbase
class UserPermission < ApplicationRecord
belongs_to :user, class_name: Userbase::User
belongs_to :permission, class_name: Userbase::Permission
end
end
用户角色模型
module Userbase
class UserRole < ApplicationRecord
belongs_to :user, class_name: Userbase::User
belongs_to :role, class_name: Userbase::Role
end
end
这是我的做法:
我在相应控制器的允许参数中添加了role_ids: []
、permission_ids: []
和user_ids: []
:
角色控制器
module Userbase
module Api
module V1
class RolesController < ApplicationController
before_action :set_role, only: %i[show update destroy]
.
.
.
private
# Use callbacks to share common setup or constraints between actions.
def set_role
@role = Userbase::Role.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def role_params
params.require(:role).permit(:name, :description, user_ids: [], permission_ids: [] )
end
end
end
end
end
用户控制器
module Userbase
module Api
module V1
class UsersController < ApplicationController
before_action :set_user, only: %i[show update destroy]
.
.
.
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@role = Userbase::User.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def role_params
params.require(:user).permit(:name, :description, role_ids: [], permission_ids: [] )
end
end
end
end
end
权限控制器
module Userbase
module Api
module V1
class PermissionsController < ApplicationController
before_action :set_permission, only: %i[show update destroy]
.
.
.
private
# Use callbacks to share common setup or constraints between actions.
def set_permission
@role = Userbase::Permission.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def role_params
params.require(:permission).permit(:name, :description, role_ids: [], user_ids: [] )
end
end
end
end
end
所以我现在可以创建权限 使用:
{
"permission": {
"name": "create_school",
"description": "This is the permission to create schools"
}
}
我们还可以创建角色 使用:
{
"role": {
"name": "Student",
"description": "This is the role for students",
"permission_ids": [1,2]
}
}
我们还可以创建用户 使用:
{
"user": {
"first_name": "Kelvin",
"middle_name": "Daniel",
"last_name": "Wale",
"email": "kelvin-wale@gmail.com",
"password": "123456",
"password_confirmation": "123456",
"username": "kelvin-wale",
"role_ids": [1],
"permission_ids": [1,2]
}
}
我还想在每次创建用户时创建一个默认角色,所以我向用户模型添加了以下方法和before_save
回调:
用户模型
module Userbase
class User < ApplicationRecord
before_save :assign_default_role
# Allow a user to have multiple permissions
has_many :user_permissions, class_name: Userbase::UserPermission, dependent: :nullify
has_many :permissions, through: :user_permissions
# Allow a user to have multiple roles
has_many :user_roles, class_name: Userbase::UserRole, dependent: :nullify
has_many :roles, through: :user_roles
end
# Assign the student role by default to users
def assign_default_role
role = Userbase::Role.find_by(name: 'Student')
self.role_ids = role.id
end
end
注意:应先创建角色,或使用以下方法将其植入数据库:
Userbase::Role.delete_all
# Default role
puts 'Creating default role'
Userbase::Role.create([{ name: 'Student',
description: 'This is the role for students',
permission_ids: [1, 2] }])
就这些了。
希望对您有所帮助
我有三个模型:Customer
、Branch
和 CustomerBranch
在客户模型中:
has_many :customer_branches, inverse_of: :customer
has_many :branches, through: :customer_branches
在分支模型中:
has_many :customer_branches, inverse_of: :branch, dependent: :restrict_with_exception
has_many :customers, through: :customer_branches
在 CustomerBranch 模型中:
belongs_to :customer, inverse_of: :customer_branches
belongs_to :branch, inverse_of: :customer_branches
这是一个仅 api 的应用程序,我将获得一组分支 ID。现在我想 assign/remove 根据收到的 ID 从客户那里分支。
我有一个解决方案来处理这个问题,但我认为这不是最好的方法。这是我目前的解决方案:
attr_accessor :branches_ids
after_save :assign_branches
def assign_branches
return if self.branches_ids.nil?
old_branch_ids = self.branch_ids
remove_branch_ids = old_branch_ids - self.branches_ids
self.customer_branches.where(id: remove_branch_ids).delete_all if remove_branch_ids.present?
self.branches << Branch.where(id: self.branches_ids)
end
有没有更好的方法来处理这个问题?提前致谢!!
好了,回答问题。您可以直接在客户上设置 ID:
customer = Customer.find(1)
customer.branches_ids = [1,2,3]
Rails 将处理所有的添加和删除。
也适用于新客户:
customer = Customer.new
customer.name = "blabla"
customer.branches_ids = [1,2,3]
customer.save
您可以在控制器中执行此操作:
def assign_branches
customer = Customer.find(params[:id]) // however you gonna get custome whom we gonna assign branches
customer.branches = Branch.where(id: params[:branch_ids]) //however way you want to get ids
end
collection= 方法通过适当地添加和删除使集合仅包含提供的对象。修改持久化到database.For更多关于关联,可以通过:https://guides.rubyonrails.org/association_basics.html#belongs-to-association-reference
在 Ubuntu 20.04[=29= 上构建 Rails 应用程序 时,我也有同样的担忧]
模型和控制器被命名为一个名为 Userbase
的模块:
用户模型
module Userbase
class User < ApplicationRecord
# Allow a user to have multiple permissions
has_many :user_permissions, class_name: Userbase::UserPermission, dependent: :nullify
has_many :permissions, through: :user_permissions
# Allow a user to have multiple roles
has_many :user_roles, class_name: Userbase::UserRole, dependent: :nullify
has_many :roles, through: :user_roles
end
end
榜样
module Userbase
class Role < ApplicationRecord
# Allow a role to have multiple users
has_many :user_roles, class_name: Userbase::UserRole, dependent: :nullify
has_many :users, through: :user_roles
# Allow a role to have multiple permissions
has_many :role_permissions, class_name: Userbase::Role, dependent: :nullify
has_many :permissions, through: :role_permissions
end
end
权限模型
module Userbase
class Permission < ApplicationRecord
# Allow a permission to have multiple users
has_many :user_permissions, class_name: Userbase::UserPermission, dependent: :nullify
has_many :users, through: :user_permissions
# Allow a permission to have multiple roles
has_many :role_permissions, class_name: Userbase::Role, dependent: :nullify
has_many :roles, through: :role_permissions
end
end
角色权限模型
module Userbase
class RolePermission < ApplicationRecord
belongs_to :role, class_name: Userbase::Role
belongs_to :permission, class_name: Userbase::Permission
end
end
用户权限模型
module Userbase
class UserPermission < ApplicationRecord
belongs_to :user, class_name: Userbase::User
belongs_to :permission, class_name: Userbase::Permission
end
end
用户角色模型
module Userbase
class UserRole < ApplicationRecord
belongs_to :user, class_name: Userbase::User
belongs_to :role, class_name: Userbase::Role
end
end
这是我的做法:
我在相应控制器的允许参数中添加了role_ids: []
、permission_ids: []
和user_ids: []
:
角色控制器
module Userbase
module Api
module V1
class RolesController < ApplicationController
before_action :set_role, only: %i[show update destroy]
.
.
.
private
# Use callbacks to share common setup or constraints between actions.
def set_role
@role = Userbase::Role.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def role_params
params.require(:role).permit(:name, :description, user_ids: [], permission_ids: [] )
end
end
end
end
end
用户控制器
module Userbase
module Api
module V1
class UsersController < ApplicationController
before_action :set_user, only: %i[show update destroy]
.
.
.
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@role = Userbase::User.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def role_params
params.require(:user).permit(:name, :description, role_ids: [], permission_ids: [] )
end
end
end
end
end
权限控制器
module Userbase
module Api
module V1
class PermissionsController < ApplicationController
before_action :set_permission, only: %i[show update destroy]
.
.
.
private
# Use callbacks to share common setup or constraints between actions.
def set_permission
@role = Userbase::Permission.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def role_params
params.require(:permission).permit(:name, :description, role_ids: [], user_ids: [] )
end
end
end
end
end
所以我现在可以创建权限 使用:
{
"permission": {
"name": "create_school",
"description": "This is the permission to create schools"
}
}
我们还可以创建角色 使用:
{
"role": {
"name": "Student",
"description": "This is the role for students",
"permission_ids": [1,2]
}
}
我们还可以创建用户 使用:
{
"user": {
"first_name": "Kelvin",
"middle_name": "Daniel",
"last_name": "Wale",
"email": "kelvin-wale@gmail.com",
"password": "123456",
"password_confirmation": "123456",
"username": "kelvin-wale",
"role_ids": [1],
"permission_ids": [1,2]
}
}
我还想在每次创建用户时创建一个默认角色,所以我向用户模型添加了以下方法和before_save
回调:
用户模型
module Userbase
class User < ApplicationRecord
before_save :assign_default_role
# Allow a user to have multiple permissions
has_many :user_permissions, class_name: Userbase::UserPermission, dependent: :nullify
has_many :permissions, through: :user_permissions
# Allow a user to have multiple roles
has_many :user_roles, class_name: Userbase::UserRole, dependent: :nullify
has_many :roles, through: :user_roles
end
# Assign the student role by default to users
def assign_default_role
role = Userbase::Role.find_by(name: 'Student')
self.role_ids = role.id
end
end
注意:应先创建角色,或使用以下方法将其植入数据库:
Userbase::Role.delete_all
# Default role
puts 'Creating default role'
Userbase::Role.create([{ name: 'Student',
description: 'This is the role for students',
permission_ids: [1, 2] }])
就这些了。
希望对您有所帮助