是否可以在模型中创建条件关联?

ton*_*all 12 conditional ruby-on-rails has-many single-table-inheritance polymorphic-associations

我已经设置了一个基于角色的访问控制系统,其中包含以下模型:

  • 角色(作为STI),
    • UserRole(全局角色)
    • ProjectRole(项目特定角色)
  • 赋值(具有不同资源的多态)
  • 用户
  • 项目(作为分配的一种资源类型)

如果用户具有特定的UserRole,则只允许用户负责该项目.此Userrole名称为"负责项目",ID为2.

在用户模型中,有两个has_many关联:responsible_assignments和responsible_projects.仅当用户具有ID为2的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
  ...
Run Code Online (Sandbox Code Playgroud)

Mik*_*rth 27

如果有人以后发现这个 - 这个功能现在实际上可以在rails 4中使用:

http://guides.rubyonrails.org/association_basics.html

语法是:

has_many :orders, -> { where processed: true }
Run Code Online (Sandbox Code Playgroud)

  • 我不认为这解决了原始问题的问题,因为它允许您按*关联*对象的字段进行过滤。但问题的作者希望仅当用户的 role_id 具有特定值时才使条件起作用 (3认同)

Rah*_*hul 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
Run Code Online (Sandbox Code Playgroud)

您希望具有特定项目角色的用户下的所有项目(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
Run Code Online (Sandbox Code Playgroud)


Yan*_*hao 5

这些关联是在加载模型时创建的。那时你的情况未知。您只能在关联中包含条件来过滤掉不需要的记录。