我已经设置了一个基于角色的访问控制系统,其中包含以下模型:
如果项目具有特定的UserRole,则只允许用户负责项目。 此Userrole名称为“负责项目”,ID为2。
在用户模型中,有两个has_many关联:responsible_assignments和responsible_projects。 只有当用户具有ID为“负责项目”的UserRole时,此关联才有效。
是否可以在用户模型中为responsible_ *关联创建条件关联,这是设置此类关系的常用方法吗?
解决此类问题的最佳做法是什么?
class Role < ActiveRecord::Base
has_many :assignments
has_many :users, :through => :assignments
class UserRole < Role
class ProjectRole < Role
class Assignment < ActiveRecord::Base
belongs_to :user
belongs_to :role
belongs_to :resource, :polymorphic => true
class User < ActiveRecord::Base
has_many :assignments
has_many :roles, :through => :assignments,
:class_name => "UserRole"
has_many :responsible_assignments, :class_name => "Assignment",
:conditions => { :role_id => 4 } // specific project role
has_many :responsible_projects, :through => :responsible_assignments,
:source => :resource,
:source_type => 'Project',
:conditions => { :status => 1 } // project is active
...
class Project < ActiveRecord
...
答案 0 :(得分:27)
如果以后有人发现这个 - 此功能现在实际上可用于rails 4:
http://guides.rubyonrails.org/association_basics.html
语法是:
has_many :orders, -> { where processed: true }
答案 1 :(得分:8)
你不能把这些条件放在关联中。这些事情在范围内处理。
阅读http://guides.rubyonrails.org/active_record_querying.html#scopes了解详情。
您的情况示例,
您希望具有特定项目角色的用户下的所有分配(ID)
scope :responsible_users, where('users.role_id = 4')
scope :select_assignment_ids, select('assignments.id')
scope :responsible_assignments, joins(:assignments).responsible_users.select_assignment_ids
您希望具有特定项目角色的用户下的所有项目(ID)都处于活动状态。
scope :active_projects, where('projects.status = 1')
scope :select_project_ids, select('projects.id')
scope :responsible_projects, joins(:assignments => :projects).responsible_users.active_projects.select_project_ids
答案 2 :(得分:1)
在加载模型时创建这些关联。那时你的病情不明。 您只能在关联中包含条件以过滤掉不需要的记录。
答案 3 :(得分:0)
我认为即使从 Rails 4.0 开始,但肯定在 5 之后,您可以像这样使用 lambda:
has_many :orders, ->(self_obj) { where('2 = ?', self_obj.role_id }
更一般地说:
has_many :children, ->(parent) { where('true = ?', parent.should_have_children? }
不确定此类解决方案的含义(父级将有条件地看不到子级,因此在需要时不会调用销毁回调等)