Можно ли создать условную ассоциацию в модели? - PullRequest
11 голосов
/ 04 марта 2012

Я установил систему управления доступом на основе ролей со следующими моделями:

  • Роль (как STI),
    • UserRole (глобальные роли)
    • ProjectRole(роли, специфичные для проекта)
  • Назначение (Полиморфный с различными ресурсами)
  • Пользователь
  • Проект (как один тип ресурса для назначений)

Пользователи могут нести ответственность за проект, только если у них есть определенная пользовательская роль.Это имя пользователя с именем «отвечает за проекты» и имеет идентификатор 2.

В модели пользователя существует две ассоциации has_many: liability_assignments и liability_projects.Эти ассоциации действительны только в том случае, если у пользователя есть UserRole, «отвечающий за проекты» с ID 2.

Возможно ли создать условную ассоциацию в пользовательской модели для ассоциацииiable_ *, и это распространенный способ настройкитакие отношения?

Как лучше всего решать такие проблемы?

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 ]

27 голосов
/ 21 мая 2015

В случае, если кто-нибудь найдет это позже - эта функция теперь фактически доступна в рельсах 4:

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

Синтаксис:

has_many :orders, -> { where processed: true }
8 голосов
/ 08 марта 2012

Вы не можете ставить такие условия в ассоциации.Такие вещи обрабатываются в областях.

Для получения дополнительной информации читайте 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

Вы хотите, чтобы все проекты (идентификаторы) под пользователем с определенной ролью проекта были активными.

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
1 голос
/ 08 марта 2012

Эти ассоциации создаются при загрузке модели. Ваше состояние неизвестно в то время. Вы можете включить в ассоциации только условия для фильтрации нежелательных записей.

...