Module: Motor::Resources::FetchConfiguredModel
- Defined in:
- lib/motor/resources/fetch_configured_model.rb
Constant Summary collapse
- CACHE_HASH =
HashWithIndifferentAccess.new
Class Method Summary collapse
- .build_configured_model(model, config) ⇒ Object
- .call(model, cache_key:) ⇒ Object
- .configure_reflection_classes(klass, cache_key) ⇒ Object
- .define_associations(klass, config) ⇒ Object
- .define_belongs_to_reflection(klass, config) ⇒ Object
- .define_class_name_method(klass, model) ⇒ Object
- .define_column_reflections(klass, config) ⇒ Object
- .define_columns_hash(klass, config) ⇒ Object
- .define_default_scope(klass, config) ⇒ Object
- .define_has_one_reflection(klass, config) ⇒ Object
- .maybe_fetch_from_cache(model, cache_key, miss_cache_block, postprocess_block) ⇒ Object
Class Method Details
.build_configured_model(model, config) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 29 def build_configured_model(model, config) klass = Class.new(model) define_class_name_method(klass, model) define_columns_hash(klass, config) define_default_scope(klass, config) define_column_reflections(klass, config) define_associations(klass, config) klass end |
.call(model, cache_key:) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 10 def call(model, cache_key:) configs = Motor::Configs::LoadFromCache.load_resources(cache_key: cache_key) maybe_fetch_from_cache( model, cache_key, lambda { resource_config = configs.find { |r| r.name == model.name.underscore } if resource_config build_configured_model(model, resource_config.preferences) else define_class_name_method(Class.new(model), model) end }, ->(klass) { configure_reflection_classes(klass, cache_key) } ) end |
.configure_reflection_classes(klass, cache_key) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 137 def configure_reflection_classes(klass, cache_key) klass.reflections.each do |key, ref| begin next unless ref.klass next if ref.klass.anonymous? rescue StandardError next end ref_dup = ref.dup if ref.klass.name == klass.name ref_dup.instance_variable_set(:@klass, klass) else ref_dup.instance_variable_set(:@klass, call(ref.klass, cache_key: cache_key)) end klass.reflections[key] = ref_dup end klass._reflections = klass.reflections klass end |
.define_associations(klass, config) ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 162 def define_associations(klass, config) config.fetch(:associations, []).each do |association| is_virtual, is_polymorphic = association.values_at(:virtual, :polymorphic) next unless is_virtual = association.slice(:foreign_key, :primary_key) [:class_name] = association[:model_name].classify [:as] = association[:foreign_key].delete_suffix('_id') if is_polymorphic = .merge(association[:options] || {}) klass.has_many(association[:name].to_sym, **.symbolize_keys) end end |
.define_belongs_to_reflection(klass, config) ⇒ Object
116 117 118 119 120 121 122 123 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 116 def define_belongs_to_reflection(klass, config) klass.belongs_to(config[:name].to_sym, class_name: config[:model_name].classify, foreign_key: config[:foreign_key], polymorphic: config[:polymorphic], primary_key: config[:primary_key], optional: true) end |
.define_class_name_method(klass, model) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 56 def define_class_name_method(klass, model) klass.instance_variable_set(:@__motor_model_name, model.name) klass.instance_eval do def name @__motor_model_name end def inspect super.gsub(/\#<Class:0x\w+>/, name) end def to_s super.gsub(/\#<Class:0x\w+>/, name) end def anonymous? true end end klass end |
.define_column_reflections(klass, config) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 101 def define_column_reflections(klass, config) config.fetch(:columns, []).each do |column| reference = column[:reference] next if reference.blank? next unless reference[:virtual] if reference[:reference_type] == 'belongs_to' define_belongs_to_reflection(klass, reference) else define_has_one_reflection(klass, reference) end end end |
.define_columns_hash(klass, config) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 80 def define_columns_hash(klass, config) return klass if config[:custom_sql].blank? columns = Resources::CustomSqlColumnsCache.call(config[:custom_sql]) columns_hash = columns.each_with_object({}) do |column, acc| acc[column[:name]] = ActiveRecord::ConnectionAdapters::Column.new(column[:name], nil) end klass.instance_variable_set(:@__motor_custom_sql_columns_hash, columns_hash) # rubocop:disable Naming/MemoizedInstanceVariableName klass.instance_eval do def columns_hash @__motor__columns_hash ||= @__motor_custom_sql_columns_hash.merge(super) end end # rubocop:enable Naming/MemoizedInstanceVariableName end |
.define_default_scope(klass, config) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 42 def define_default_scope(klass, config) return klass if config[:custom_sql].blank? klass.instance_variable_set(:@__motor_custom_sql, config[:custom_sql].squish) klass.instance_eval do default_scope do from(Arel.sql("(#{self.klass.instance_variable_get(:@__motor_custom_sql)})").as(table_name)) end end klass end |
.define_has_one_reflection(klass, config) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 125 def define_has_one_reflection(klass, config) = { class_name: config[:model_name].classify, foreign_key: config[:foreign_key], primary_key: config[:primary_key] } = .merge(config[:options] || {}) klass.has_one(config[:name].to_sym, **.symbolize_keys) end |
.maybe_fetch_from_cache(model, cache_key, miss_cache_block, postprocess_block) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/motor/resources/fetch_configured_model.rb', line 178 def maybe_fetch_from_cache(model, cache_key, miss_cache_block, postprocess_block) return miss_cache_block.call unless cache_key if CACHE_HASH[model.name] && CACHE_HASH[model.name][:key] == cache_key CACHE_HASH[model.name][:value] else result = miss_cache_block.call CACHE_HASH[model.name] = { key: cache_key, value: result } postprocess_block.call(result) end end |