Frage Ist es möglich, eine bedingte Assoziation im Modell zu erstellen?


Ich habe ein rollenbasiertes Zugriffskontrollsystem mit den folgenden Modellen eingerichtet:

  • Rolle (als STI),
    • UserRole (globale Rollen)
    • ProjectRole (projektspezifische Rollen)
  • Zuordnung (polymorph mit verschiedenen Ressourcen)
  • Benutzer
  • Projekt (als ein Ressourcentyp für Zuordnungen)

Benutzer dürfen nur dann für ein Projekt verantwortlich sein, wenn sie eine bestimmte UserRole haben. Diese Userrolle hat den Namen "verantwortlich für Projekte" und hat die ID 2.

Im Benutzermodell gibt es zwei has_many-Zuordnungen: responsible_assignments und responsible_projects. Diese Verknüpfungen sind nur gültig, wenn der Benutzer die UserRole "verantwortlich für Projekte" mit ID 2 hat.

Ist es möglich, im Benutzermodell eine bedingte Zuordnung für die Zuordnung "responsible_ *" zu erstellen, und ist dies eine übliche Methode zum Einrichten dieser Art von Beziehungen?

Was ist die beste Vorgehensweise, um diese Art von Problemen zu lösen?

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
  ...

11
2018-03-04 15:31


Ursprung


Antworten:


Sie können solche Bedingungen nicht in Assoziationen setzen. Solche Dinge werden in Bereichen gehandhabt.

Lesen http://guides.rubyonrails.org/active_record_querying.html#scopes für mehr Informationen.

Beispiel für deine Situation,

Sie möchten alle Zuordnungen (IDs) unter einem Benutzer mit einer bestimmten Projektrolle

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

Sie möchten alle Projekte (IDs) unter einem Benutzer mit einer bestimmten Projektrolle, die aktiv sind.

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

7
2018-03-08 05:40



Für den Fall, dass jemand das später findet - diese Funktion ist jetzt tatsächlich in Rails 4 verfügbar:

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

Syntax ist:

has_many :orders, -> { where processed: true }

24
2018-05-21 10:37



Diese Verknüpfungen werden beim Laden des Modells erstellt. Dein Zustand ist zu dieser Zeit unbekannt. Sie können nur die Bedingungen in die Verknüpfungen aufnehmen, um unerwünschte Datensätze herauszufiltern.


1
2018-03-08 04:05