Module: ActiveRecord::Mti::ClassMethods
- Defined in:
- lib/mti.rb
Class Method Summary collapse
-
.as_base_instance ⇒ Object
Thread safe execution of a block in a “base instance mode”.
-
.instantiate(*_) ⇒ Object
Override ActiveRecord’s instantiation method which builds an object from a record Return the base class object when in “base instance mode” and the implementation object otherwise.
Instance Method Summary collapse
Class Method Details
.as_base_instance ⇒ Object
Thread safe execution of a block in a “base instance mode”
55 56 57 58 59 60 61 62 |
# File 'lib/mti.rb', line 55 def self.as_base_instance @@base_instance_mode_lock.synchronize do @@base_instance_mode = true result = yield @@base_instance_mode = false result end end |
.instantiate(*_) ⇒ Object
Override ActiveRecord’s instantiation method which builds an object from a record Return the base class object when in “base instance mode” and the implementation object otherwise
46 47 48 49 50 51 52 |
# File 'lib/mti.rb', line 46 def self.instantiate(*_) if @@base_instance_mode super else super.public_send(mti_name) end end |
Instance Method Details
#mti_base ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/mti.rb', line 27 def mti_base class_attribute :mti_name self.mti_name = self.to_s.underscore.to_sym @@base_instance_mode = false @@base_instance_mode_lock = Mutex.new # Always fetch with the implementation default_scope lambda { includes(mti_name) } # Implementation model association belongs_to mti_name, polymorphic: true, inverse_of: mti_name # Override ActiveRecord's instantiation method # which builds an object from a record # Return the base class object when in "base instance mode" # and the implementation object otherwise def self.instantiate(*_) if @@base_instance_mode super else super.public_send(mti_name) end end # Thread safe execution of a block in a "base instance mode" def self.as_base_instance @@base_instance_mode_lock.synchronize do @@base_instance_mode = true result = yield @@base_instance_mode = false result end end end |
#mti_implementation_of(mti_base_name) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/mti.rb', line 65 def mti_implementation_of(mti_base_name) class_attribute :mti_base self.mti_base = mti_base_name.to_s.classify.constantize # Base model association has_one mti_base_name.to_sym, :as => mti_base_name.to_sym, :autosave => true, :dependent => :destroy, :validate => true, :inverse_of => mti_base_name.to_sym # When calling the base object from the implementation # switch the base's class to the "base instance mode" # to receive the base class object instead of another # implementation object and avoid an infinite loop define_method "#{mti_base_name}_with_reverse" do # def role_with_reverse mti_base.as_base_instance do # Role.as_base_instance do send("#{mti_base_name}_without_reverse") # role_without_reverse end # end end # end alias_method_chain mti_base_name, :reverse # alias_method_chain :role, :reverse # Auto build base model define_method "#{mti_base_name}_with_autobuild" do # def role_with_autobuild public_send("#{mti_base_name}_without_autobuild") || # role_without_autobuild || public_send("build_#{mti_base_name}") # build_role end # end alias_method_chain mti_base_name, :autobuild # alias_method_chain :role, :autobuild # Delegate attributes mti_base.content_columns.map(&:name).each do |attr| delegate attr, "#{attr}=", "#{attr}?", :to => mti_base_name.to_sym end # Delegate associations mti_base.reflections.keys .tap { |k| k.delete(mti_base_name.to_sym) } .each do |association| delegate association, "#{association}=", :to => mti_base_name.to_sym end delegate_missing_to mti_base_name accepts_nested_attributes_for mti_base_name define_method "#{mti_base_name}_id" do public_send(mti_base_name).id end end |