Module: DuckRecord::Inheritance::ClassMethods

Defined in:
lib/duck_record/inheritance.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#abstract_classObject

Set this to true if this is an abstract class (see abstract_class?). If you are using inheritance with DuckRecord and don’t want child classes to utilize the implied STI table name of the parent class, this will need to be true. For example, given the following:

class SuperClass < DuckRecord::Base
  self.abstract_class = true
end
class Child < SuperClass
  self.table_name = 'the_table_i_really_want'
end

self.abstract_class = true is required to make Child<.find,.create, or any Arel method> use the_table_i_really_want instead of a table called super_classes



85
86
87
# File 'lib/duck_record/inheritance.rb', line 85

def abstract_class
  @abstract_class
end

Instance Method Details

#abstract_class?Boolean

Returns whether this class is an abstract class or not.

Returns:

  • (Boolean)


88
89
90
# File 'lib/duck_record/inheritance.rb', line 88

def abstract_class?
  defined?(@abstract_class) && @abstract_class == true
end

#base_classObject

Returns the class descending directly from DuckRecord::Base, or an abstract class, if any, in the inheritance hierarchy.

If A extends DuckRecord::Base, A.base_class will return A. If B descends from A through some arbitrarily deep hierarchy, B.base_class will return A.

If B < A and C < B and if A is an abstract_class then both B.base_class and C.base_class would return B as the answer since A is an abstract_class.



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/duck_record/inheritance.rb', line 58

def base_class
  unless self < Base
    raise DuckRecordError, "#{name} doesn't belong in a hierarchy descending from DuckRecord"
  end

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

#inherited(subclass) ⇒ Object



92
93
94
95
# File 'lib/duck_record/inheritance.rb', line 92

def inherited(subclass)
  subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
  super
end

#new(*args, &block) ⇒ Object

Determines if one of the attributes passed in is the inheritance column, and if the inheritance column is attr accessible, it initializes an instance of the given subclass instead of the base class.



42
43
44
45
46
47
48
# File 'lib/duck_record/inheritance.rb', line 42

def new(*args, &block)
  if abstract_class? || self == Base
    raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated."
  end

  super
end