Class: RailsAiContext::Tools::MigrationAdvisor
- Defined in:
- lib/rails_ai_context/tools/migration_advisor.rb
Constant Summary collapse
- VALID_ACTIONS =
%w[add_column remove_column rename_column add_index add_association change_type create_table].freeze
Constants inherited from BaseTool
BaseTool::SESSION_CONTEXT, BaseTool::SHARED_CACHE
Class Method Summary collapse
Methods inherited from BaseTool
abstract!, abstract?, cache_key, cached_context, config, extract_method_source_from_file, extract_method_source_from_string, find_closest_match, fuzzy_find_key, inherited, not_found_response, paginate, rails_app, registered_tools, reset_all_caches!, reset_cache!, session_queries, session_record, session_reset!, set_call_params, text_response
Class Method Details
.call(action: nil, table: nil, column: nil, type: nil, new_name: nil, options: nil, server_context: nil) ⇒ Object
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 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/rails_ai_context/tools/migration_advisor.rb', line 48 def self.call(action: nil, table: nil, column: nil, type: nil, new_name: nil, options: nil, server_context: nil) action = action.to_s.strip table = table.to_s.strip column = column.to_s.strip.presence if column # Normalize model names to table names: "Cook" → "cooks", "BrandProfile" → "brand_profiles" table = table.underscore.pluralize if table.match?(/\A[A-Z]/) return text_response("**Error:** `action` is required. Valid actions: #{VALID_ACTIONS.join(', ')}") if action.empty? return text_response("**Error:** `table` is required (e.g., 'users', 'posts').") if table.empty? # Validate identifier characters to produce valid migration code unless table.match?(/\A[a-z_][a-z0-9_]*\z/) return text_response("**Error:** Invalid table name `#{table}`. Use lowercase letters, digits, and underscores only.") end # create_table uses column param as a comma-separated column:type definition string if action != "create_table" && column && !column.empty? && !column.match?(/\A[a-z_][a-z0-9_]*\z/) return text_response("**Error:** Invalid column name `#{column}`. Use lowercase letters, digits, and underscores only.") end unless VALID_ACTIONS.include?(action) suggestion = VALID_ACTIONS.find { |a| a.start_with?(action) || a.include?(action) } hint = suggestion ? " Did you mean `#{suggestion}`?" : "" return text_response("**Error:** Unknown action `#{action}`.#{hint} Valid actions: #{VALID_ACTIONS.join(', ')}") end schema = cached_context[:schema] models = cached_context[:models] lines = [ "# Migration Advisor", "" ] # Check if table exists table_exists = schema.is_a?(Hash) && !schema[:error] && schema[:tables]&.key?(table) case action when "add_column" lines.concat(generate_add_column(table, column, type, , table_exists)) when "remove_column" lines.concat(generate_remove_column(table, column, type, schema, models)) when "rename_column" rename_to = new_name&.to_s&.strip rename_to = type if rename_to.nil? || rename_to.empty? lines.concat(generate_rename_column(table, column, rename_to)) when "add_index" lines.concat(generate_add_index(table, column, )) when "add_association" lines.concat(generate_add_association(table, column, type, )) when "change_type" lines.concat(generate_change_type(table, column, type, )) when "create_table" lines.concat(generate_create_table(table, column, )) end # Show affected models lines.concat(show_affected_models(table, models)) # Strong Migrations warnings (only when the gem is present in the project) lines.concat(strong_migrations_warnings(action, table, column, )) if strong_migrations_gem_present? text_response(lines.join("\n")) end |