Возможно ли создать условную ассоциацию в модели?
Я настроил систему управления доступом на основе ролей со следующими моделями:
- роль (как ИППП),
- роль пользователя (глобальные роли)
- ProjectRole (проектные роли)
- назначение (полиморфное с различными ресурсами)
- пользователь
- проект (как один из типов ресурсов для назначений)
В пользовательской модели есть две ассоциации has_many: responsible_assignments и responsible_projects. Эти ассоциации действительны только в том случае, если пользователь имеет роль пользователя "ответственный за проекты" с идентификатором 2.
Можно ли создать условную ассоциацию в пользовательской модели для ассоциации 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
...
3 ответа:
Вы не можете ставить такие условия в ассоциациях. Такие вещи обрабатываются в области видимости.
Читать http://guides.rubyonrails.org/active_record_querying.html#scopes для получения дополнительной информации.
Пример для вашей ситуации,
Вы хотите, чтобы все назначения (идентификаторы) выполнялись пользователем с определенной ролью проекта
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
В случае, если кто - то найдет это позже- эта функция теперь фактически доступна в rails 4:
Http://guides.rubyonrails.org/association_basics.html
Синтаксис:
has_many :orders, -> { where processed: true }