
डिक्लेरेटिव प्राधिकरण लाइब्रेरी जिसमें नीति नियम, शर्तें और कैशिंग लिखने के लिए DSL है। यह Ruby अनुप्रयोगों के लिए स्केलेबल, DRY अनुमति प्रबंधन सक्षम करती है।
DeclarativePolicy: एक घोषणात्मक प्राधिकरण लाइब्रेरीयह लाइब्रेरी प्राधिकरण नीतियां लिखने के लिए एक DSL प्रदान करती है।
इसका उपयोग तर्क को अनुमतियों से अलग करने के लिए किया जा सकता है, और GitLab.com पर उत्पादन में बड़े पैमाने पर उपयोग किया गया है।
इस लाइब्रेरी के मूल लेखक Jeanine Adkisson हैं, और कॉपीराइट GitLab के पास है।
अपने एप्लिकेशन के Gemfile में यह पंक्ति जोड़ें:
gem 'declarative_policy'
और फिर निष्पादित करें:
$ bundle install
या इसे स्वयं इस प्रकार स्थापित करें:
$ gem install declarative_policy
require 'declarative_policy'
class User
attr_reader :name
def initialize(name:)
@name = name
end
end
class Vehicle
def initialize(owner:, trusted: [])
@owner = owner
@trusted = trusted
end
def owner?(user)
@owner.name == user.name
end
def trusted?(user)
@owner.name == user.name || @trusted.detect { |t| t.name == user.name }
end
end
class VehiclePolicy < DeclarativePolicy::Base
condition(:owns) { @subject.owner?(@user) }
condition(:trusted) { @subject.trusted?(@user) }
rule { owns }.enable :sell_vehicle
rule { trusted }.enable :drive_vehicle
end
jack = User.new(name: 'jack')
jill = User.new(name: 'jill')
jacks_vehicle = Vehicle.new(owner: jack, trusted: [jill])
jills_vehicle = Vehicle.new(owner: jill, trusted: [jack])
puts "Jack can drive Jack's vehicle? -> #{DeclarativePolicy.policy_for(jack, jacks_vehicle).can?(:drive_vehicle)}"
puts "Jack can drive Jill's vehicle? -> #{DeclarativePolicy.policy_for(jack, jills_vehicle).can?(:drive_vehicle)}"
puts "Jack can sell Jack's vehicle? -> #{DeclarativePolicy.policy_for(jack, jacks_vehicle).can?(:sell_vehicle)}"
puts "Jack can sell Jill's vehicle? -> #{DeclarativePolicy.policy_for(jack, jills_vehicle).can?(:sell_vehicle)}"
$ ruby example.rb
Jack can drive Jack's vehicle? -> true
Jack can drive Jill's vehicle? -> true
Jack can sell Jack's vehicle? -> true
Jack can sell Jill's vehicle? -> false
इस लाइब्रेरी का मुख्य अमूर्तन एक Policy है। नीतियां संयोजित करती हैं:
conditions कहा जाता है) दुनिया की स्थिति के बारे मेंrules कहा जाता है)यह लाइब्रेरी निम्नलिखित रूप के कथनों का सत्य मान निर्धारित करने के लिए मौजूद है:
User Predicate [Subject]
User का नाम बदलकर Actor और Subject का नाम बदलकर Resource करने पर इस मुद्दे में चर्चा की गई है।
उदाहरण के लिए:
user :is_aliveuser :can_drive caruser :can_sell carयह हमें वाक्यों की वस्तुओं के साथ एक Policy (नियमों का एक सेट जो बताता है कि कौन से कथन सत्य हैं) को संबद्ध करके ऐसा करता है। एक कथन को सत्य माना जाता है यदि कोई नियम इसे prevents नहीं करता है, और कम से कम एक नियम इसे enables करता है।
उदाहरण के लिए, कल्पना करें कि हमारे पास वाहनों और उपयोगकर्ताओं वाला एक डेटा मॉडल है, और हम जानना चाहते हैं कि कोई उपयोगकर्ता वाहन चला सकता है या नहीं। हमें एक VehiclePolicy की आवश्यकता है:
class VehiclePolicy < DeclarativePolicy::Base
# relevant facts
condition(:owns) { @subject.owner == @user }
condition(:has_access_to) { @subject.owner.trusts?(@user) }
condition(:old_enough_to_drive) { @user.age >= laws.minimum_age }
condition(:has_driving_license) { @user.driving_license&.valid? }
# expensive rules can have 'score'. Higher scores are 'more expensive' to calculate
condition(:owns, score: 0) { @subject.owner == @user }
condition(:has_access_to, score: 3) { @subject.owner.trusts?(@user) }
condition(:intoxicated, score: 5) { @user.blood_alcohol > laws.max_blood_alcohol }
# conclusions we can draw:
rule { owns }.enable :drive_vehicle
rule { has_access_to }.enable :drive_vehicle
rule { ~old_enough_to_drive }.prevent :drive_vehicle
rule { intoxicated }.prevent :drive_vehicle
rule { ~has_driving_license }.prevent :drive_vehicle
# we can use methods to abstract common logic
def laws
@subject.registration.country.driving_laws
end
end
ध्यान देने योग्य कुछ बातें: हम इसे एक बड़े नियम के रूप में लिख सकते थे ((owns | has_access_to) & old_enough_to_drive & ~intoxicated & has_driving_license) लेकिन हम कुछ विशेषताएं देख सकते हैं जो घोषणात्मक नीतियों को बड़े सिस्टम के लिए स्केलेबल बनाती हैं: नियमों को छोटे तत्वों में तोड़ा जा सकता है, और बड़े नियमों में संयोजित किया जा सकता है। किसी भी समय नई शर्तें और नियम जोड़े जा सकते हैं।
जो देखना अधिक कठिन है वह यह है कि कई प्रदर्शन अनुकूलन हमारे लिए पारदर्शी रूप से संभाले जाते हैं:
संक्षेप में, इस लाइब्रेरी का उद्देश्य घोषणात्मक होना है: हम उन नियमों की घोषणा करते हैं जो महत्वपूर्ण हैं, और लाइब्रेरी उनका मूल्यांकन कैसे करें इसकी व्यवस्था करती है।
कैशिंग नीतियों की एक विशेष रूप से मूल्यवान विशेषता है। यदि हम वाहन बेचने के बारे में नए नियम जोड़ते हैं, उदाहरण के लिए:
rule { owns }.enable :sell_vehicle
तब स्वामित्व का तथ्य नीति पर विभिन्न कॉलों के बीच साझा किया जा सकता है, जिससे डेटाबेस कॉल और अन्य महंगे I/O ऑपरेशन बचते हैं।
हम निम्न के साथ एक नीति का निर्धारण जांच सकते हैं:
cache = Session.current_session
policy = DeclarativePolicy.policy_for(user, car, cache: cache)
policy.can?(:drive_vehicle)
अधिक उपयोग विवरण के लिए, दस्तावेज़ीकरण देखें।
रिपॉजिटरी को चेक आउट करने के बाद, निर्भरताएं स्थापित करने के लिए bundle install चलाएं। फिर, परीक्षण चलाने के लिए rake spec चलाएं। आप प्रयोग करने की अनुमति देने वाले इंटरैक्टिव प्रॉम्प्ट के लिए bin/console भी चला सकते हैं।
इस जेम को अपनी स्थानीय मशीन पर स्थापित करने के लिए, bundle exec rake install चलाएं। एक नया संस्करण जारी करने के लिए, version.rb में संस्करण संख्या अपडेट करें, और फिर bundle exec rake release चलाएं, जो संस्करण के लिए एक git टैग बनाएगा, git कमिट और टैग पुश करेगा, और .gem फ़ाइल को rubygems.org पर पुश करेगा।
नीतियों और कस्टम भूमिकाओं पर अधिक विवरण निम्नलिखित पृष्ठों पर पाए जा सकते हैं:
बग रिपोर्ट और मर्ज अनुरोध GitLab पर https://gitlab.com/gitlab-org/ruby/gems/declarative-policy पर स्वागत है। यह परियोजना सहयोग के लिए एक सुरक्षित, स्वागत योग्य स्थान होने का इरादा रखती है, और योगदानकर्ताओं से GitLab आचार संहिता का पालन करने की अपेक्षा की जाती है।
हम declarative_policy को आवश्यकतानुसार जारी करते हैं। हम कब जारी करते हैं इसकी कोई नियमितता नहीं है, हम तब जारी करते हैं जब हम कोई बदलाव करते हैं - चाहे बदलाव का आकार कुछ भी हो।
एक नया संस्करण जारी करने के लिए:
Gemfile को अपडेट करने की सिफारिश की जाती है ताकि declarative_policy Ruby जेम को भी नए संस्करण पर ले जाया जा सके।यह जेम MIT लाइसेंस की शर्तों के तहत ओपन सोर्स के रूप में उपलब्ध है।
DeclarativePolicy परियोजना के कोडबेस, मुद्दा ट्रैकर्स, चैट रूम और मेलिंग सूचियों में बातचीत करने वाले सभी लोगों से आचार संहिता का पालन करने की अपेक्षा की जाती है।