10

मैं रेल 3.2 एप पर काम कर रहा हूं जहां मैं प्रमाणीकरण के लिए डेविस का उपयोग करता हूं। मैंने उपयोगकर्ता भूमिकाओं के प्रबंधन के लिए एकल तालिका विरासत का प्रयास करने का निर्णय लिया, लेकिन मैं जल्दी से एक समस्या में भाग गया। वर्तमान में मेरे पास तीन उपयोगकर्ता मॉडल हैं, User < ActiveRecord, Admin < User और Collaborator < User। व्यवस्थापक और सहयोगी अधिकांश उपयोगकर्ता कॉलम साझा करते हैं, लेकिन उनके पास थोड़ा अलग व्यवहार और विशेषाधिकार हैं। मेरे मॉडल वर्तमान में इस तरह दिखता है:रेल 3.2 में कई मॉडलों का उपयोग करते समय मैं डेविस के साथ प्रमाणीकरण कैसे संभाल सकता हूं। ऐप

# Causes problem, no one can access anything. 
before_filter :authenticate_admin! 
before_filter :authenticate_collaborator! 

ऐसा ही एक समस्या मैं था:

class User < ActiveRecord::Base 

    devise :database_authenticatable, :registerable, 
    :recoverable, :rememberable, :trackable, :validatable, :token_authenticatable 

    # Setup accessible (or protected) attributes for your model 
    attr_accessible :email, :name, :password, :password_confirmation, :remember_me 

    before_save :ensure_authentication_token 

    [...] 

end 

class Admin < User 
    has_one :account, dependent: :destroy 
    attr_accessible :account_attributes 
    accepts_nested_attributes_for :account 
end 


class Collaborator < User 
    has_one :account 
end 

class Account < ActiveRecord::Base 
    attr_accessible :name 
    validates_presence_of :name 
    has_many :projects, dependent: :destroy 
    has_many :users 
end 

समस्या मेष जब मैं (जहाँ मैं प्रमाणीकरण की जरूरत है और अन्य नियंत्रक) व्यवस्थापक और सहयोगी प्रमाणित करने के लिए मेरी ProjectController में कोशिश यानी के लिए devise के सहायक तरीकों के साथ था। current_user, अब मैं current_admin है और current_collaborator, मैं "हल" है कि पहले एक बनाने के द्वारा फिल्टर और विधि:

def set_current_user 
    @current_user = current_admin || current_collaborator 
end 

वहाँ वसीयत के साथ अपने प्रमाणीकरण समस्या के लिए एक समान या सरल उपाय है, या आप से एक और दृष्टिकोण की सिफारिश करेंगे एकल टेबल विरासत, और वह क्या होगा?

मेरा लक्ष्य है, 1. जब नए उपयोगकर्ता साइन अप करते हैं, तो वे व्यवस्थापक बन जाते हैं, जब वे अपना खाता बनाते हैं, तो खाता मॉडल भी बनाया जाता है। 2. नया (व्यवस्थापक) उपयोगकर्ता तब अतिरिक्त उपयोगकर्ताओं को खाते में आमंत्रित कर सकता है, जो सहयोगी होंगे। 3. व्यवस्थापक और सहयोगी के पास अलग-अलग विशेषाधिकार होना चाहिए। जब वे साइन अप करते हैं तो सहयोगी नए "खाते" नहीं बनाएंगे (कंपनी मेरे खाता मॉडल के लिए एक बेहतर नाम हो सकती है) इसलिए व्यवस्थापक और सहयोगियों को साइन अप करने और संपादित करने के लिए थोड़ा अलग रूपों की आवश्यकता होगी।

धन्यवाद।

अद्यतन

मैं थोड़े फिल्टर से पहले एक ऐसी ही बनाने के द्वारा "हल" यह: संभवतः अधिक सुरुचिपूर्ण समाधान पर

def authenticate! 
    if @current_user == current_admin 
    :authenticate_admin! 
    elsif @current_user == current_collaborator 
    :authenticate_collaborator! 
    end 
end 

सुझाव अभी भी सराहना की जाएगी।

+0

मिल मेरा उत्तर परीक्षण करने के लिए एक मौका का उपयोग कर हल कर सकते हैं? – blnc

उत्तर

1

आप सभी सामान्य तर्क मॉड्यूल में अलग कर सकते हैं और केवल उसी तालिका का उपयोग कर सकते हैं।

module UserMethods 
    #... 
end 

class User < ActiveRecord::Base 
    include UserMethods 
    devise ... 

end 

class Admin < ActiveRecord::Base 
    include UserMethods 
    self.table_name = "users" 
    devise ... 
end 

और मार्गों में अलग से सभी वसीयत मॉडल कॉन्फ़िगर करते हैं, दृश्य (यदि आवश्यक हो, Configuring Views देखें)। इस मामले में, आप सभी अलग तर्क को आसान संसाधित कर सकते हैं।

+0

एमएम, धन्यवाद। ऐसा लगता है कि काम करेगा। हालांकि, यह समाधान मेरे वर्तमान समाधान से बेहतर कैसे है? मेरे नए सवाल के लिए खेद है। यहाँ एक और आता है। मैं अपने तर्क को थोड़ा बदलने की सोच रहा हूं, और उपयोगकर्ताओं को कई खातों के लिए अनुमति देता हूं, या तो प्रत्येक खाते के लिए व्यवस्थापक या सहयोगी, उपयोगकर्ता और खाते के बीच कई से अधिक रिश्ते, मैं इसे आपके या मेरे समाधान के साथ कैसे प्राप्त कर सकता हूं, और अभी भी अलग भूमिकाएं हैं? धन्यवाद! – Anders

+0

मॉड्यूल को शामिल करने के बजाय, आप सभी तर्कों को सामान्य मॉडल में निकाल सकते हैं, उदाहरण के लिए, बेसयूसर, यहां सभी रिश्ते रखें। लेकिन सभी अलग तर्क, रचना या विशेषताओं से संबंधित, आप मॉडल को अलग करने के लिए रख सकते हैं। अर्थात। ऐसा लगता है कि आपका और मेरा दृष्टिकोण संयुक्त होना चाहिए। मुझे तरीकों में 'अगर' स्थितियां पसंद नहीं हैं, क्योंकि यह ओओपी शैली नहीं है। – gayavat

3

सुनिश्चित नहीं हैं कि अगर यह इस के लिए एक समाधान ...

एक और अधिक सुरुचिपूर्ण तरीका डबल प्रमाणीकरणों के लिए निम्न करने के लिए हो सकता है अभी भी जरूरत है:

private 

def authenticate! 
    :authenticate_admin! || :authenticate_collaborator! 
    @current_user = admin_signed_in? ? current_admin : current_collaborator 
end 

फिर before_filter फोन: प्रमाणित !

यदि आपको सार्वभौमिक '@current_user' चर की आवश्यकता नहीं है तो बस दूसरी पंक्ति छोड़ दें।

उम्मीद है कि इससे मदद मिलती है।

+0

यह समाधान काम नहीं करता है क्योंकि अगर विफल रहता है तो प्रमाणीकरण_एडमिन रीडायरेक्ट करेगा ... कोई विचार? मैं इसे – Rafal

+0

पर काम नहीं कर सकता, आप सही हैं, नवीनतम संस्करणों में यह अब काम नहीं करता है। मैं देखूंगा कि मैं चारों ओर एक काम पा सकता हूं। – blnc

+0

मैंने अपने समाधान के साथ एक जवाब जोड़ा – Rafal

5

आप इस निम्नलिखित समाधान

 
def authenticate! 
    if modelA_user_signed_in? 
     @current_user = current_modelA 
     true 
    else 
     authenticate_modelB! 
    end 

    end