2013-01-18 47 views
8

मैं user.rb के लिए एक मॉडल है, जिसमें मैं admins के लिए एक गुंजाइश है, जो भूमिका है कि उपयोगकर्ताओं को परिभाषित है एक अनुमति तालिका के माध्यम से व्यवस्थापक के।रेल ActiveRecord स्कोप वह यह है कि एक और गुंजाइश की "विपरीत", या है उन "कमी" एक संपत्ति

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

गुंजाइश इस तरह काम करता है:

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

मैं भी जो सभी उपयोगकर्ताओं व्यवस्थापक भूमिका न हो है एक गुंजाइश non-admins या ऐसा ही कुछ कहा जाता है बनाने के लिए, चाहते हैं।

ऐसा करने का सबसे आसान तरीका क्या है?

उत्तर

0

एक आसान तरीका है, जो उपयोगकर्ताओं का एक बहुत के लिए performant नहीं होगा:

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

पहली पंक्ति का एक तेज तरीका 'admin_user_ids = User.admins.pluck (: id)' – mylescc

6

आप एक औंधा SQL क्वेरी करना चाहते हैं, तो आप इसे अपने आप को ऐसा करने के लिए मैन्युअल रूप से करना होगा। कोई अंतर्निहित ActiveRecord समाधान नहीं है।

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

अगर कोई स्कोप के एक बहुत हैं या वे जटिल हैं, आईडी से बहिष्कृत कर:

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

और पंक्तियों की संख्या मूल प्रश्न की जटिलता पर निर्भर करता है, यह धीमी या तेज हो सकता है पिछले तरीके से।

+0

आपके दायरे समाधानों के लिए होगा, मुझे समस्या है कि जब मैं शामिल होता हूं और विलय करता हूं, तो यह केवल उन ऑब्जेक्ट्स को ध्यान में रखें जिनके पास संबंधित ऑब्जेक्ट्स हैं। मेरे मामले में मैं उपयोगकर्ता + अनुमति से निपट नहीं रहा हूं। तो मुझे संबंधित वस्तुओं के साथ एक झूठी संपत्ति, और संबंधित वस्तुओं के बिना सभी वस्तुओं के लिए एक सेट वापस करने की जरूरत है। और आपका रास्ता मेरे लिए काम नहीं करता है – miguelfg