我想知道是否有更优雅的方式通过关系链接has_many。在我的示例中,我有一个可以拥有多个角色的用户。每个角色都有多个权限。因此用户具有多个权限。下面的代码工作正常,但我很想知道是否有更好的方法来做到这一点。
class User < ActiveRecord::Base
has_many :role_user_mappings
has_many :roles, through: :role_user_mappings
def permissions
permitted_actions = []
self.roles.each do |role|
role.permissions.each do |permission|
permitted_actions << permission
end
end
permitted_actions
end
end
class Role < ActiveRecord::Base
has_many :permission_role_mappings
has_many :permissions, through: :permission_role_mappings
end
class Permission < ActiveRecord::Base
end
class PermissionRoleMapping < ActiveRecord::Base
belongs_to :permission
belongs_to :role
end
class RoleUserMapping < ActiveRecord::Base
belongs_to :user
belongs_to :role
end
我希望能够做到这一点。
user.permissions
编辑:尝试 在我尝试的事情上,至少干掉用户模型一点点就是将功能添加为关注点
module Permittable
extend ActiveSupport::Concern
def permissions
permitted_actions = []
self.roles.each do |role|
role.permissions.each do |permission|
permitted_actions << permission
end
end
permitted_actions
end
end
答案 0 :(得分:3)
你试过..
class User < ActiveRecord::Base
has_many :role_user_mappings
has_many :roles, through: :role_user_mappings
has_many :permissions, through: roles
那应该给你
user.permissions
我不确定HMT通过HMT功能何时可用,我知道它在早期版本的rails中缺失,但它适用于我在Rails 5上。
答案 1 :(得分:1)
如果你这样做:
class Permission < ActiveRecord::Base
has_many :permission_role_mappings
end
然后你应该能够做到这一点:
class User < ActiveRecord::Base
has_many :role_user_mappings
has_many :roles, through: :role_user_mappings
def permissions
Permission.
joins(:permission_role_mappings).
where(permission_role_mappings: {role: roles})
end
end
顺便说一下,你可能已经知道了这一点,这可能就是你问这个问题的原因......但是这会给你一个N + 1查询:
permitted_actions = []
self.roles.each do |role|
role.permissions.each do |permission|
permitted_actions << permission
end
end
permitted_actions
此外,FWIW,当想要从集合中回来array
时,您不需要这样做:
permitted_actions = []
self.roles.each do |role|
...
end
permitted_actions
你可以这样做:
roles.map do |role|
...
end
由于map
会返回array
。