Ruby on Rails 5.2 - ActiveRecord::Inheritance::ClassMethods

मॉड्यूल ActiveRecord :: वंशानुक्रम :: ClassMethods




ruby

मॉड्यूल ActiveRecord :: वंशानुक्रम :: ClassMethods

गुण

abstract_class [RW]

इसे true सेट करें यदि यह एक सार वर्ग है (देखें abstract_class? )। यदि आप सक्रिय रिकॉर्ड के साथ इनहेरिटेंस का उपयोग कर रहे हैं और एसटीआई पदानुक्रम के हिस्से के रूप में माना जाने वाला वर्ग नहीं चाहते हैं, तो आपको इसे सही पर सेट करना होगा। ApplicationRecord , उदाहरण के लिए, एक अमूर्त वर्ग के रूप में उत्पन्न होता है।

निम्नलिखित डिफ़ॉल्ट व्यवहार पर विचार करें:

Shape = Class.new(ActiveRecord::Base)
Polygon = Class.new(Shape)
Square = Class.new(Polygon)

Shape.table_name   # => "shapes"
Polygon.table_name # => "shapes"
Square.table_name  # => "shapes"
Shape.create!      # => #<Shape id: 1, type: nil>
Polygon.create!    # => #<Polygon id: 2, type: "Polygon">
Square.create!     # => #<Square id: 3, type: "Square">

हालाँकि, abstract_class का उपयोग करते समय, Shape को पदानुक्रम से हटा दिया जाता है:

class Shape < ActiveRecord::Base
  self.abstract_class = true
end
Polygon = Class.new(Shape)
Square = Class.new(Polygon)

Shape.table_name   # => nil
Polygon.table_name # => "polygons"
Square.table_name  # => "polygons"
Shape.create!      # => NotImplementedError: Shape is an abstract class and cannot be instantiated.
Polygon.create!    # => #<Polygon id: 1, type: nil>
Square.create!     # => #<Square id: 2, type: "Square">

ध्यान दें कि उपरोक्त उदाहरण में, एक सादा Polygon की रचना को Polygon , आपको इसे एक अमूर्त वर्ग के रूप में सेट करने के बजाय validates :type, presence: true उपयोग करना चाहिए। इस तरह, Polygon पदानुक्रम में रहेगा, और सक्रिय रिकॉर्ड तालिका के नाम को सही ढंग से प्राप्त करना जारी रखेगा।

सार्वजनिक प्रवृत्ति के तरीके

# File activerecord/lib/active_record/inheritance.rb, line 151
def abstract_class?
  defined?(@abstract_class) && @abstract_class == true
end

लौटता है कि क्या यह वर्ग एक अमूर्त वर्ग है या नहीं।

# File activerecord/lib/active_record/inheritance.rb, line 95
def base_class
  unless self < Base
    raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
  end

  if superclass == Base || superclass.abstract_class?
    self
  else
    superclass.base_class
  end
end

ActiveRecord::Base से सीधे उतरता वर्ग ActiveRecord::Base , या एक सार वर्ग, यदि कोई हो, वंशानुक्रम पदानुक्रम में।

यदि A ActiveRecord::Base विस्तार करता है ActiveRecord::Base , A.base_class ए वापस आएगा। यदि B कुछ मनमाने ढंग से गहरी पदानुक्रम के माध्यम से A से उतरता है, तो B.base_class ए वापस आ जाएगा

यदि B <A और C <B और यदि A #abstract_class तो B.Base_class और C.base_class दोनों B को उत्तर देंगे क्योंकि A एक सार_क्लास है।

descends_from_active_record? () स्रोत दिखाएं
# File activerecord/lib/active_record/inheritance.rb, line 72
def descends_from_active_record?
  if self == Base
    false
  elsif superclass.abstract_class?
    superclass.descends_from_active_record?
  else
    superclass == Base || !columns_hash.include?(inheritance_column)
  end
end

अगर यह एसटीआई प्रकार की स्थिति की आवश्यकता नहीं true तो true । यदि STI प्रकार की स्थिति लागू करने की आवश्यकता है, तो false देता है।

विरासत में मिला (उपवर्ग) शो स्रोत
# File activerecord/lib/active_record/inheritance.rb, line 163
def inherited(subclass)
  subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
  super
end
सुपरक्लास विधि कहता है
नया (विशेषताएँ = शून्य, और ब्लॉक) दिखाएँ स्रोत
# File activerecord/lib/active_record/inheritance.rb, line 50
def new(attributes = nil, &block)
  if abstract_class? || self == Base
    raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated."
  end

  if has_attribute?(inheritance_column)
    subclass = subclass_from_attributes(attributes)

    if subclass.nil? && base_class == self
      subclass = subclass_from_attributes(column_defaults)
    end
  end

  if subclass && subclass != self
    subclass.new(attributes, &block)
  else
    super
  end
end

यह निर्धारित करता है कि पारित विशेषताओं में से एक वंशानुक्रम स्तंभ है, और यदि वंशानुक्रम स्तंभ सुलभ है, तो यह बेस क्लास के बजाय दिए गए उपवर्ग का एक उदाहरण इनिशियलाइज़ करता है।

सुपरक्लास विधि कहता है
# File activerecord/lib/active_record/inheritance.rb, line 159
def polymorphic_name
  base_class.name
end
# File activerecord/lib/active_record/inheritance.rb, line 155
def sti_name
  store_full_sti_class ? name : name.demodulize
end

संरक्षित उदाहरण तरीके

compute_type (type_name) स्रोत दिखाएं
# File activerecord/lib/active_record/inheritance.rb, line 172
def compute_type(type_name)
  if type_name.start_with?("::".freeze)
    # If the type is prefixed with a scope operator then we assume that
    # the type_name is an absolute reference.
    ActiveSupport::Dependencies.constantize(type_name)
  else
    type_candidate = @_type_candidates_cache[type_name]
    if type_candidate && type_constant = ActiveSupport::Dependencies.safe_constantize(type_candidate)
      return type_constant
    end

    # Build a list of candidates to search for
    candidates = []
    name.scan(/::|$/) { candidates.unshift "#{$`}::#{type_name}" }
    candidates << type_name

    candidates.each do |candidate|
      constant = ActiveSupport::Dependencies.safe_constantize(candidate)
      if candidate == constant.to_s
        @_type_candidates_cache[type_name] = candidate
        return constant
      end
    end

    raise NameError.new("uninitialized constant #{candidates.first}", candidates.first)
  end
end

एक उपसर्ग के रूप में वर्तमान मॉड्यूल का उपयोग करके रिकॉर्ड का वर्ग प्रकार लौटाता है। तो MyApp के वंशज :: व्यवसाय :: खाता MyApp :: Business :: AccountSubclass के रूप में दिखाई देगा।