Ruby on Rails 5.2 - ActiveRecord::Base

वर्ग ActiveRecord :: बेस




ruby

वर्ग ActiveRecord :: बेस

जनक:
Object
शामिल मॉड्यूल:
ActiveRecord::Core , ActiveRecord::Persistence , ActiveRecord :: ActiveRecord::ModelSchema , ActiveRecord::ModelSchema , ActiveRecord::Inheritance , ActiveRecord :: Scoping , ActiveRecord :: Sanitization , ActiveRecord :: AttributeAssignment , ActiveModel::Conversion ActiveRecord::Integration ActiveRecord::Validations ActiveRecord::DefineCallbacks , ActiveRecord::AttributeMethods ActiveRecord::DefineCallbacks , ActiveRecord::AttributeMethods , ActiveRecord::Callbacks ActiveRecord::Locking::Optimistic , ActiveRecord::Locking::Pessimistic , ActiveRecord::DefineCallbacks ActiveRecord::AttributeMethods , ActiveRecord::Callbacks , ActiveRecord::Timestamp , ActiveRecord :: एसोसिएशन , ActiveModel::SecurePassword , ActiveRecord::AutosaveAssociation AutosaveAssociation , ActiveRecord :: NestedAttributes , ActiveRecord::Aggregations , ActiveRecord::Transactions , ActiveRecord :: TouchLater , ActiveRecord :: NoRouching , ActiveRecord :: :: सीरियलाइज़ेशन , ActiveRecord::Store , ActiveRecord :: SecureToken , ActiveRecord::Suppressor यंत्र

सक्रिय रिकॉर्ड

सक्रिय रिकॉर्ड ऑब्जेक्ट सीधे उनकी विशेषताओं को निर्दिष्ट नहीं करते हैं, बल्कि उन्हें उस तालिका परिभाषा से अनुमान लगाते हैं जिसके साथ वे जुड़े हुए हैं। जोड़ने और हटाने, और बदलते विशेषताओं और उनके प्रकार सीधे डेटाबेस में किया जाता है। सक्रिय रिकॉर्ड ऑब्जेक्ट्स में कोई भी परिवर्तन तुरंत परिलक्षित होता है। किसी निश्चित डेटाबेस तालिका में दिए गए सक्रिय रिकॉर्ड वर्ग को बांधने वाली मैपिंग अधिकांश सामान्य मामलों में स्वचालित रूप से होगी, लेकिन असामान्य लोगों के लिए अधिलेखित की जा सकती है।

अधिक जानकारी के लिए table_name में मैपिंग नियम और फ़ाइलों / activerecord / README_rdoc.html में पूर्ण उदाहरण देखें।

सृष्टि

सक्रिय रिकॉर्ड कंस्ट्रक्टर मापदंडों को या तो हैश में या एक ब्लॉक के रूप में स्वीकार करता है। जब आप कहीं और से डेटा प्राप्त कर रहे हों, तो हैश मेथड विशेष रूप से उपयोगी होता है, जैसे HTTP अनुरोध। यह इस तरह काम करता है:

user = User.new(name: "David", occupation: "Code Artist")
user.name # => "David"

आप ब्लॉक आरंभीकरण का उपयोग भी कर सकते हैं:

user = User.new do |u|
  u.name = "David"
  u.occupation = "Code Artist"
end

और निश्चित रूप से आप केवल एक नंगे ऑब्जेक्ट बना सकते हैं और तथ्य के बाद विशेषताओं को निर्दिष्ट कर सकते हैं:

user = User.new
user.name = "David"
user.occupation = "Code Artist"

शर्तेँ

शर्तों को या तो एक स्ट्रिंग, ऐरे के रूप में निर्दिष्ट किया जा सकता है, या SQL कथन के WHERE-part का प्रतिनिधित्व करते हुए हैश किया जा सकता है। सरणी प्रपत्र का उपयोग तब किया जाता है जब स्थिति इनपुट दागी जाती है और स्वच्छता की आवश्यकता होती है। स्ट्रिंग फॉर्म का उपयोग स्टेटमेंट के लिए किया जा सकता है जिसमें दागी डेटा शामिल नहीं है। हैश फॉर्म सरणी फॉर्म की तरह बहुत काम करता है, केवल समानता और सीमा को छोड़कर संभव है। उदाहरण:

class User < ActiveRecord::Base
  def self.authenticate_unsafely(user_name, password)
    where("user_name = '#{user_name}' AND password = '#{password}'").first
  end

  def self.authenticate_safely(user_name, password)
    where("user_name = ? AND password = ?", user_name, password).first
  end

  def self.authenticate_safely_simply(user_name, password)
    where(user_name: user_name, password: password).first
  end
end

authenticate_unsafely विधि सीधे पैरामीटर को क्वेरी में सम्मिलित करती है और इस प्रकार SQL- इंजेक्शन के हमलों के लिए अतिसंवेदनशील होती है यदि उपयोगकर्ता_नाम और password पैरामीटर सीधे HTTP अनुरोध से आते हैं। authenticate_safely और authenticate_safely_simply user_name दोनों क्वेरी में डालने से पहले उपयोगकर्ता_नाम और password को user_name करेगा, जो यह सुनिश्चित करेगा कि एक हमलावर क्वेरी से बच नहीं सकता है और लॉगिन (या बदतर) को नकली कर सकता है।

स्थितियों में कई मापदंडों का उपयोग करते समय, यह आसानी से पढ़ने के लिए मुश्किल हो सकता है कि चौथे या पांचवें प्रश्न चिह्न का प्रतिनिधित्व क्या करना है। उन मामलों में, आप इसके बजाय नामित बाइंड चर का सहारा ले सकते हैं। यह प्रतीकों के साथ प्रश्न चिह्न को बदलने और मिलान चिह्न कुंजियों के लिए मानों के साथ हैश की आपूर्ति द्वारा किया जाता है:

Company.where(
  "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
  { id: 3, name: "37signals", division: "First", accounting_date: '2005-01-01' }
).first

इसी तरह, एक बयान के बिना एक साधारण हैश SQL और ऑपरेटर के साथ समानता के आधार पर स्थितियां उत्पन्न करेगा। उदाहरण के लिए:

Student.where(first_name: "Harvey", status: 1)
Student.where(params[:student])

SQL BETWEEN ऑपरेटर का उपयोग करने के लिए हैश में एक श्रेणी का उपयोग किया जा सकता है:

Student.where(grade: 9..12)

SQL IN ऑपरेटर का उपयोग करने के लिए हैश में एक सरणी का उपयोग किया जा सकता है:

Student.where(grade: [9,11,12])

तालिकाओं में शामिल होने के दौरान, प्रपत्र। Table_name.column_name ’में लिखे गए नेस्टेड हैश या कुंजियों का उपयोग किसी विशेष स्थिति के तालिका नाम को अर्हता प्राप्त करने के लिए किया जा सकता है। उदाहरण के लिए:

Student.joins(:schools).where(schools: { category: 'public' })
Student.joins(:schools).where('schools.category' => 'public' )

डिफॉल्ट एक्सेसर्स को ओवरराइट करना

सभी स्तंभ मान सक्रिय रिकॉर्ड ऑब्जेक्ट पर मूल एक्सेसर्स के माध्यम से स्वचालित रूप से उपलब्ध होते हैं, लेकिन कभी-कभी आप इस व्यवहार को विशेषज्ञ बनाना चाहते हैं। यह डिफ़ॉल्ट एक्सेसर्स को अधिलेखित करके (विशेषता के समान नाम का उपयोग करके) किया जा सकता है और super को वास्तव में चीजों को बदलने के लिए कॉल कर सकता है।

class Song < ActiveRecord::Base
  # Uses an integer of seconds to hold the length of the song

  def length=(minutes)
    super(minutes.to_i * 60)
  end

  def length
    super / 60
  end
end

क्वेरी विधियों को शामिल करें

बुनियादी एक्सेसर्स के अलावा, क्वेरी विधियां भी स्वचालित रूप से सक्रिय रिकॉर्ड ऑब्जेक्ट पर उपलब्ध हैं। क्वेरी विधियाँ आपको यह परखने की अनुमति देती हैं कि क्या कोई विशेषता मान मौजूद है। इसके अतिरिक्त, जब संख्यात्मक मानों के साथ काम करते हैं, तो एक क्वेरी विधि झूठी हो जाएगी यदि मान शून्य है।

उदाहरण के लिए, name विशेषता के साथ एक सक्रिय रिकॉर्ड उपयोगकर्ता का एक name? विधि जिसे आप यह निर्धारित करने के लिए कॉल कर सकते हैं कि क्या उपयोगकर्ता का नाम है:

user = User.new(name: "David")
user.name? # => true

anonymous = User.new(name: "")
anonymous.name? # => false

टाइपिंग विशेषताओं को एक्सेस करने से पहले उन्हें टाइपकास्ट किया गया है

कभी-कभी आप चाहते हैं कि कॉलम-निर्धारित टाइपकास्ट किए बिना कच्चे विशेषता डेटा को पढ़ने में सक्षम हो। जो कि सभी विशेषताओं वाले <attribute>_before_type_cast का उपयोग करके किया जा सकता है। उदाहरण के लिए, यदि आपके खाते के मॉडल में एक balance विशेषता है, तो आप account.balance_before_type_cast या account.id_before_type_cast को कॉल कर सकते हैं।

यह सत्यापन स्थितियों में विशेष रूप से उपयोगी है जहां उपयोगकर्ता एक पूर्णांक फ़ील्ड के लिए एक स्ट्रिंग की आपूर्ति कर सकता है और आप एक त्रुटि संदेश में मूल स्ट्रिंग को वापस प्रदर्शित करना चाहते हैं। सामान्य रूप से विशेषता को एक्सेस करने से स्ट्रिंग को 0 पर टाइप किया जाएगा, जो कि आप नहीं चाहते हैं।

गतिशील विशेषता-आधारित खोजक

डायनेमिक विशेषता-आधारित खोजक SQL को चालू किए बिना सरल प्रश्नों द्वारा वस्तुओं को प्राप्त करने (और / या बनाने) का एक मामूली रूप से पदावनत तरीका है। वे find_by_ जैसे Person.find_by_user_name को एक विशेषता का नाम जोड़कर काम करते हैं। Person.find_by(user_name: user_name) लिखने के बजाय, आप Person.find_by_user_name(user_name) उपयोग कर सकते हैं।

डायनामिक खोजकर्ताओं के अंत में एक सक्रियकरण बिंदु जोड़ने के लिए एक विस्मयादिबोधक बिंदु (!) जोड़ना संभव है, यदि कोई रिकॉर्ड नहीं लौटाते हैं तो Person.find_by_last_name! त्रुटि, जैसे कि Person.find_by_last_name!

" और " के साथ उन्हें अलग करके एक ही find_by_ में कई विशेषताओं का उपयोग करना संभव है।

Person.find_by(user_name: user_name, password: password)
Person.find_by_user_name_and_password(user_name, password) # with dynamic finder

संबंधों और नामित स्कॉप्स पर इन गतिशील खोजक विधियों को कॉल करना संभव है।

Payment.order("created_on").find_by_amount(50)

टेक्स्ट कॉलम में एरेज़, हैश और अन्य गैर-अनुपयोगी वस्तुओं को सहेजना

सक्रिय रिकॉर्ड YAML का उपयोग करके पाठ कॉलम में किसी भी वस्तु को क्रमबद्ध कर सकता है। ऐसा करने के लिए, आपको इसे कॉल टू क्लास विधि के साथ निर्दिष्ट करना होगा। यह किसी भी अतिरिक्त काम किए बिना सरणियों, हैश, और अन्य गैर-अनुपयोगी वस्तुओं को संग्रहीत करना संभव बनाता है।

class User < ActiveRecord::Base
  serialize :preferences
end

user = User.create(preferences: { "background" => "black", "display" => large })
User.find(user.id).preferences # => { "background" => "black", "display" => large }

आप एक वर्ग विकल्प को दूसरे पैरामीटर के रूप में भी निर्दिष्ट कर सकते हैं जो एक अपवाद को बढ़ाएगा यदि धारावाहिक ऑब्जेक्ट को पदानुक्रम में नहीं वर्ग के वंशज के रूप में पुनर्प्राप्त किया जाता है।

class User < ActiveRecord::Base
  serialize :preferences, Hash
end

user = User.create(preferences: %w( one two three ))
User.find(user.id).preferences    # raises SerializationTypeMismatch

जब आप एक वर्ग विकल्प निर्दिष्ट करते हैं, तो उस विशेषता के लिए डिफ़ॉल्ट मान उस वर्ग का एक नया उदाहरण होगा।

class User < ActiveRecord::Base
  serialize :preferences, OpenStruct
end

user = User.new
user.preferences.theme_color = "red"

एकल तालिका वंशानुक्रम

सक्रिय रिकॉर्ड डिफ़ॉल्ट रूप से "प्रकार" नाम वाले स्तंभ में वर्ग का नाम संग्रहीत करके वंशानुक्रम की अनुमति देता है। ActiveRecord::Inheritance देखें ActiveRecord::Inheritance अधिक जानकारी के लिए ActiveRecord::Inheritance

विभिन्न मॉडलों में कई डेटाबेस से कनेक्शन

कनेक्शन आमतौर पर ActiveRecord::Base.establish_connection के माध्यम से बनाए ActiveRecord::Base.establish_connection और ActiveRecord :: Base.connection द्वारा पुनर्प्राप्त किए जाते हैं। ActiveRecord::Base से विरासत में मिली सभी कक्षाएं इस कनेक्शन का उपयोग करेंगी। लेकिन आप एक वर्ग-विशिष्ट कनेक्शन भी सेट कर सकते हैं। उदाहरण के लिए, यदि कोर्स एक ActiveRecord::Base , लेकिन एक अलग डेटाबेस में रहता है, तो आप बस कह सकते हैं Course.establish_connection और कोर्स और इसके सभी उपवर्ग इसके बजाय इस कनेक्शन का उपयोग करेंगे।

इस सुविधा को ActiveRecord::Base में एक कनेक्शन पूल रखते हुए कार्यान्वित किया जाता है जो कि वर्ग द्वारा अनुक्रमित एक हैश है। यदि कनेक्शन का अनुरोध किया जाता है, तो ActiveRecord::Base.retrieve_connection विधि क्लास-पदानुक्रम तक जाएगी जब तक कि कनेक्शन पूल में एक कनेक्शन नहीं मिलता है।

अपवाद

  • ActiveRecordError - जेनेरिक त्रुटि वर्ग और सक्रिय रिकॉर्ड द्वारा उठाए गए अन्य सभी त्रुटियों का सुपरक्लास।

  • AdapterNotSpecified - ActiveRecord::Base.establish_connection में उपयोग किए गए कॉन्फ़िगरेशन हैश ActiveRecord::Base.establish_connection में एक :adapter कुंजी शामिल नहीं है।

  • AdapterNotFound - The :adapter ActiveRecord::Base.establish_connection में उपयोग की जाने वाली :adapter कुंजी ActiveRecord::Base.establish_connection एक गैर-मौजूद एडॉप्टर (या किसी मौजूदा की खराब वर्तनी) को निर्दिष्ट करता है।

  • AssociationTypeMismatch - AssociationTypeMismatch को सौंपी गई वस्तु एसोसिएशन की परिभाषा में निर्दिष्ट प्रकार की नहीं थी।

  • AttributeAssignmentError - ActiveRecord::Base#attributes= विधि के माध्यम से बड़े पैमाने पर असाइनमेंट करते समय एक त्रुटि हुई। आप अपवाद ऑब्जेक्ट की attribute गुण का निर्धारण कर सकते हैं कि किस विशेषता ने त्रुटि को ट्रिगर किया।

  • ConnectionNotEstablished - कोई कनेक्शन स्थापित नहीं किया गया है। ActiveRecord::Base.establish_connection क्वेरी करने से पहले ActiveRecord::Base.establish_connection उपयोग करें।

  • MultiparameterAssignmentErrors - ActiveRecord::Base#attributes= विधि का उपयोग करके एक बड़े असाइनमेंट के दौरान हुई त्रुटियों का संग्रह। इस अपवाद की errors संपत्ति में AttributeAssignmentError ऑब्जेक्ट की एक सरणी होती है, जिसे यह निर्धारित करने के लिए निरीक्षण किया जाना चाहिए कि कौन सी विशेषताएँ त्रुटियों को ट्रिगर करती हैं।

  • RecordInvalid - ActiveRecord::Base#save! द्वारा उठाया गया ActiveRecord::Base#save! और ActiveRecord::Base.create! जब रिकॉर्ड अमान्य है।

  • ActiveRecord::RecordNotFound - ActiveRecord::Base.find विधि का जवाब नहीं दिया गया। या तो दी गई आईडी वाली पंक्ति मौजूद नहीं है या पंक्ति अतिरिक्त प्रतिबंधों को पूरा नहीं करती है। कुछ ActiveRecord::Base.find कॉल इस अपवाद को नहीं बढ़ाते हैं कि संकेत कुछ भी नहीं मिला है, कृपया अधिक जानकारी के लिए इसके प्रलेखन की जांच करें।

  • SerializationTypeMismatch - क्रमबद्ध ऑब्जेक्ट दूसरे पैरामीटर के रूप में निर्दिष्ट वर्ग का नहीं था।

  • StatementInvalid - डेटाबेस सर्वर ने SQL स्टेटमेंट को अस्वीकार कर दिया। संदेश में सटीक त्रुटि जोड़ी गई है।

नोट : सूचीबद्ध विशेषताएँ वर्ग-स्तरीय विशेषताएँ (वर्ग और उदाहरण स्तर दोनों से सुलभ) हैं। इसलिए Base.logger= माध्यम से कक्षा के लिए एक लकड़हारा असाइन करना संभव है, जो तब वर्तमान ऑब्जेक्ट स्पेस में सभी उदाहरणों द्वारा उपयोग किया जाएगा।