2013-01-18 9 views
8

Ich habe ein Modell für user.rb, in dem ich einen Bereich für admins definieren, die Benutzer sind, die die Rolle haben von Admin durch eine Berechtigungstabelle.Rails ActiveRecord Bereich, der das "Gegenteil" eines anderen Bereichs ist, oder Benutzer, die eine Eigenschaft "fehlt"

has_many :permissions 
has_many :roles, :through => :permissions 

Der Umfang funktioniert wie folgt:

scope :admins, joins(:permissions).merge(Permission.admin_permissions) 

Ich würde auch einen Bereich non-admins oder so ähnlich genannt machen möchten, die alle Benutzer, die die Admin-Rolle nicht haben.

Was ist der einfachste Weg, dies zu tun?

Antwort

0

Eine einfache Möglichkeit, die nicht performant für viele Anwender sein würde:

admin_user_ids = User.admins.map(&:id) 
non_admin_users = User.all.reject { |u| admin_user_ids.include?(u.id) } 
+1

Ein schneller Weg der ersten Zeile wäre zu tun 'admin_user_ids = User.admins.pluck (: id)' – mylescc

6

Wenn Sie eine invertierte SQL-Abfrage haben wollen, müssen Sie es selbst manuell zu tun. Es gibt keine integrierte ActiveRecord-Lösung.

scope :admins, joins(:permissions).merge(Permission.where("permissions.admin = true")) 
scope :non_admins, joins(:permissions).merge(Permission.where("permissions.admin = false")) 

Wenn es viele Bereiche gibt, oder sie sind komplex, betrachten sie durch ID ohne:

User.where("id not in (?)", User.admins.pluck(:id)) 

# or if you are already using admin records 
admins = User.admins 
User.where("id not in (?)", admins.map(&:id)) 

auf Anzahl der Zeilen und die Komplexität der ursprünglichen Abfrage Je könnte dies langsamer oder schneller als der vorherige Weg.

+0

Für Ihre Scope-Lösungen, ich habe das Problem, dass wenn ich einen Beitritt und Zusammenführen, wird es nur Berücksichtigen Sie Objekte, die verwandte Objekte erstellt haben. In meinem Fall habe ich es nicht mit User + Permission zu tun. Also muss ich eine Menge für alle Objekte mit verwandten Objekten mit einer falschen Eigenschaft und alle Objekte ohne verwandte Objekte zurückgeben. Und dein Weg funktioniert nicht für mich – miguelfg