Class: MegaBar::Model
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- MegaBar::Model
- Includes:
- MegaBarModelConcern
- Defined in:
- app/models/mega_bar/model.rb
Instance Attribute Summary collapse
-
#make_page ⇒ Object
Returns the value of attribute make_page.
-
#model_id ⇒ Object
writeonly
Sets the attribute model_id.
Class Method Summary collapse
-
.deterministic_id(classname) ⇒ Object
Deterministic ID generation for Models ID range: 9000-9999.
Instance Method Summary collapse
-
#create_essential_fields_after_migration ⇒ Object
Public methods for testing and manual execution.
- #find_model_displays_for_position_fields ⇒ Object
- #make_all_files ⇒ Object
- #make_page_for_model ⇒ Object
- #make_position_field ⇒ Object
- #my_constantize(class_name) ⇒ Object
- #populate_positions(parent_model) ⇒ Object
- #pos ⇒ Object
- #standardize_classname ⇒ Object
- #standardize_modyule ⇒ Object
-
#standardize_tablename ⇒ Object
must come after standardize_modyule.
Instance Attribute Details
#make_page ⇒ Object
Returns the value of attribute make_page.
17 18 19 |
# File 'app/models/mega_bar/model.rb', line 17 def make_page @make_page end |
#model_id=(value) ⇒ Object (writeonly)
Sets the attribute model_id
18 19 20 |
# File 'app/models/mega_bar/model.rb', line 18 def model_id=(value) @model_id = value end |
Class Method Details
.deterministic_id(classname) ⇒ Object
Deterministic ID generation for Models ID range: 9000-9999
28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'app/models/mega_bar/model.rb', line 28 def self.deterministic_id(classname) # Use classname to create unique identifier identifier = classname.to_s hash = Digest::MD5.hexdigest(identifier) base_id = 9000 + (hash.to_i(16) % 1000) # Check for collisions and increment if needed while MegaBar::Model.exists?(id: base_id) base_id += 1 break if base_id >= 10000 # Don't overflow into next range end base_id end |
Instance Method Details
#create_essential_fields_after_migration ⇒ Object
Public methods for testing and manual execution
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'app/models/mega_bar/model.rb', line 214 def create_essential_fields_after_migration logger.info("đ§ create_essential_fields_after_migration called for #{self.classname}") logger.info("đ§ Creating essential fields after migration for #{self.classname}...") logger.info("đ Current fields before post-migration creation: #{MegaBar::Field.by_model(self.id).pluck(:field).join(', ')}") # Always create id field if it doesn't exist id_field_exists = MegaBar::Field.by_model(self.id).where(field: 'id').exists? logger.info("đ ID field exists after migration: #{id_field_exists}") unless id_field_exists logger.info("đ Creating id field for #{self.classname}") begin id_field = MegaBar::Field.create!( model_id: self.id, field: 'id', data_type: 'integer', tablename: self.tablename, default_data_format: 'textread', default_data_format_edit: 'textread' ) logger.info("â Created id field for #{self.classname} (ID: #{id_field.id})") rescue => e logger.error("â Failed to create id field: #{e.message}") logger.error("â Error class: #{e.class}") logger.error("â Error backtrace: #{e.backtrace.first(3).join(', ')}") end else logger.info("âšī¸ ID field already exists after migration for #{self.classname}") end # Always create name field if it doesn't exist name_field_exists = MegaBar::Field.by_model(self.id).where(field: 'name').exists? logger.info("đ Name field exists after migration: #{name_field_exists}") unless name_field_exists logger.info("đ Creating name field for #{self.classname}") begin name_field = MegaBar::Field.create!( model_id: self.id, field: 'name', data_type: 'string', tablename: self.tablename, default_data_format: 'textread', default_data_format_edit: 'textbox' ) logger.info("â Created name field for #{self.classname} (ID: #{name_field.id})") rescue => e logger.error("â Failed to create name field: #{e.message}") logger.error("â Error class: #{e.class}") logger.error("â Error backtrace: #{e.backtrace.first(3).join(', ')}") end else logger.info("âšī¸ Name field already exists after migration for #{self.classname}") end # Create position field if position_parent is set logger.info("đ Calling make_position_field after migration...") make_position_field logger.info("â Essential fields created after migration for #{self.classname}") logger.info("đ Final fields after post-migration creation: #{MegaBar::Field.by_model(self.id).pluck(:field).join(', ')}") end |
#find_model_displays_for_position_fields ⇒ Object
191 192 193 194 195 196 197 |
# File 'app/models/mega_bar/model.rb', line 191 def find_model_displays_for_position_fields mds = [] Block.find(ModelDisplay.by_model(self.id).by_action("index").pluck(:block_id)).each do |block| mds << block.model_displays.by_action("index").pluck(:id).first end mds end |
#make_all_files ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 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 |
# File 'app/models/mega_bar/model.rb', line 43 def make_all_files logger.info("đ STARTING make_all_files for #{self.classname} (ID: #{self.id})") logger.info("đ Model details: name=#{self.name}, tablename=#{self.tablename}, position_parent=#{self.position_parent}") # Step 1: Generate all files first (model, controller, migration) logger.info("đ STEP 1: Generating files for #{self.classname}") logger.info("creating scaffold for " + self.classname + 'via: ' + 'rails g mega_bar:mega_bar ' + self.classname + ' ' + self.id.to_s) mod = self.modyule.nil? || self.modyule.empty? ? 'no_mod' : self.modyule logger.info("đ§ Module: #{mod}") # Generate model files and migrations using system call (most reliable for production) logger.info("đ¨ Invoking MegaBar generator for #{self.classname}...") generator_command = "rails g mega_bar:mega_bar_models #{mod} #{self.classname} #{self.id.to_s} #{pos}" logger.info("đ Generator command: #{generator_command}") logger.info("đ Position parameter: #{pos}") generator_result = system(generator_command) logger.info("đ Generator system call result: #{generator_result}") if generator_result logger.info("â Generator completed successfully for #{self.classname}") else logger.error("â Generator failed for #{self.classname}") # Try with bundle exec as fallback bundle_command = "bundle exec #{generator_command}" logger.info("đ Trying with bundle exec: #{bundle_command}") bundle_result = system(bundle_command) logger.info("đ Bundle exec result: #{bundle_result}") if bundle_result logger.info("â Generator completed successfully with bundle exec for #{self.classname}") else logger.error("â Generator failed even with bundle exec for #{self.classname}") logger.info("â ī¸ Continuing anyway - we'll create essential fields and try migrations later") end end # Step 2: Create essential fields immediately (don't wait for migrations) logger.info("đ§ STEP 2: Creating essential fields for #{self.classname}") create_essential_fields # Step 3: Run migrations last (with better error handling) logger.info("đ STEP 3: Running migrations for #{self.classname}") run_migrations_safely # Step 4: Handle CCCUX setup logger.info("đ STEP 4: Setting up CCCUX for #{self.classname}") logger.info("đ Reloading model for discovery...") reload_new_model_for_discovery logger.info("đ Creating CCCUX permissions...") logger.info("đ COMPLETED make_all_files for #{self.classname}") end |
#make_page_for_model ⇒ Object
104 105 106 107 108 109 110 111 112 113 |
# File 'app/models/mega_bar/model.rb', line 104 def make_page_for_model if !self.make_page.nil? && !self.make_page.blank? mod = self.modyule.nil? || self.modyule.empty? ? '' : self.modyule.underscore + '/' path = '/' + mod.dasherize + self.classname.underscore.dasherize.pluralize # path = self.make_page == 'default_model_path' ? path : self.make_page page = MegaBar::Page.find_or_initialize_by(path: path) page.assign_attributes(name: self.name + ' Model Page', path: path, make_layout_and_block: self.make_page, mega_page: self.mega_model, base_name: self.name, model_id: self.id) page.save unless page.id end end |
#make_position_field ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'app/models/mega_bar/model.rb', line 143 def make_position_field logger.info("đ make_position_field called for #{self.classname}") logger.info("đ Position field exists: #{MegaBar::Field.by_model(self.id).where(field: 'position').exists?}") logger.info("đ Position parent blank: #{self.position_parent.blank?}") logger.info("đ Position parent: '#{self.position_parent}'") unless MegaBar::Field.by_model(self.id).where(field: 'position').empty? && !self.position_parent.blank? logger.info("âī¸ Skipping position field creation - conditions not met") return end logger.info("đ Creating position field for #{self.classname}") begin mds = find_model_displays_for_position_fields logger.info("đ Found model displays for position field: #{mds.inspect}") # Temporarily skip table validation for position field position_field = MegaBar::Field.new( model_id: self.id, field: 'position', tablename: self.tablename, data_type: 'integer', default_data_format: 'textread', default_data_format_edit: 'textbox', model_display_ids: mds ) # Skip validation for position field that will be created after migration position_field.save!(validate: false) logger.info("â Created position field for #{self.classname} (ID: #{position_field.id})") parent_model = MegaBar::Model.find_by( modyule: self.position_parent.split("::")[0...-1].join("::"), classname: self.position_parent.split("::").last ) logger.info("đ Parent model found: #{parent_model ? parent_model.classname : 'nil'}") populate_positions(parent_model) if parent_model logger.info("â Position field setup completed for #{self.classname}") rescue => e logger.error("â Failed to create position field for #{self.classname}: #{e.message}") logger.error("â Error class: #{e.class}") logger.error("â Error backtrace: #{e.backtrace.first(5).join(', ')}") end end |
#my_constantize(class_name) ⇒ Object
115 116 117 118 119 120 121 |
# File 'app/models/mega_bar/model.rb', line 115 def my_constantize(class_name) #not in use unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ class_name raise NameError, "#{class_name.inspect} is not a valid constant name!" end Object.module_eval("::#{$1}", __FILE__, __LINE__) end |
#populate_positions(parent_model) ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'app/models/mega_bar/model.rb', line 198 def populate_positions(parent_model) # modle = Model.find(model_id) # modle_name = modle.modyule ? modle.modyule + "::" + modle.classname : modle.classname modle_name = self.modyule ? self.modyule + "::" + self.classname : self.classname return unless defined?(modle_name) == 'constant' && modle_name.class == Class mod = modle_name.constantize mod.reset_column_information # warning: metaprogramming ahead! mod.distinct((parent_model.classname.underscore.downcase + '_id').to_sym).map(&parent_model.classname.underscore.downcase.to_sym).each do |parent| parent.send(self.classname.underscore.downcase.pluralize.to_sym).order(:id).each_with_index do |child, i| child.update_columns(position: i + 1) end end end |
#pos ⇒ Object
97 98 99 100 101 |
# File 'app/models/mega_bar/model.rb', line 97 def pos return 'none' unless position_parent.present? return 'acts_as_list' if position_parent == 'pnp' "acts_as_list scope: :#{position_parent.gsub('::', '_').singularize.underscore.sub(/^_/, '')} unless Rails.env.test? ".split(' ').join('^') end |
#standardize_classname ⇒ Object
135 136 137 |
# File 'app/models/mega_bar/model.rb', line 135 def standardize_classname self.classname = self.classname.classify end |
#standardize_modyule ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 |
# File 'app/models/mega_bar/model.rb', line 123 def standardize_modyule return if self.modyule.nil? || self.modyule.empty? self.modyule = self.modyule.gsub('megabar', 'MegaBar') self.modyule = self.modyule.chomp('::').chomp(':').chomp('/').reverse.chomp('::').chomp(':').chomp('/').reverse self.modyule = self.modyule.gsub('-', '_') self.modyule = self.modyule.gsub('/', '::') self.modyule = self.modyule.split('::').map { | m | m = m.gsub('-', '_') m = m.classify }.join('::') end |
#standardize_tablename ⇒ Object
must come after standardize_modyule
139 140 141 |
# File 'app/models/mega_bar/model.rb', line 139 def standardize_tablename # must come after standardize_modyule self.tablename = self.modyule.nil? || self.modyule.empty? ? self.classname.pluralize.underscore : self.modyule.split('::').map { | m | m = m.underscore }.join('_') + '_' + self.classname.pluralize.underscore end |