Module: Profitable::JsonHelpers
- Included in:
- Profitable
- Defined in:
- lib/profitable/json_helpers.rb
Constant Summary collapse
- VALID_TABLE_COLUMN_PATTERN =
Regex patterns for validating SQL identifiers to prevent SQL injection Only allows: alphanumeric characters, underscores, and dots (for table.column format)
/\A[a-zA-Z_][a-zA-Z0-9_.]*\z/- VALID_JSON_KEY_PATTERN =
/\A[a-zA-Z_][a-zA-Z0-9_]*\z/
Instance Method Summary collapse
-
#json_extract(table_column, json_key) ⇒ String
Returns the appropriate JSON extraction syntax for the current database adapter, always yielding a TEXT-typed value so comparisons behave identically everywhere.
Instance Method Details
#json_extract(table_column, json_key) ⇒ String
Returns the appropriate JSON extraction syntax for the current database adapter, always yielding a TEXT-typed value so comparisons behave identically everywhere. Supports PostgreSQL, MySQL (5.7.9+), and SQLite.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/profitable/json_helpers.rb', line 30 def json_extract(table_column, json_key) # Validate inputs to prevent SQL injection validate_table_column!(table_column) validate_json_key!(json_key) adapter = ActiveRecord::Base.connection.adapter_name.downcase case adapter when /postgres/ "#{table_column} ->> '#{json_key}'" when /mysql/, /trilogy/ # MySQL 5.7.9+ supports JSON_EXTRACT and ->> operator # We use JSON_UNQUOTE(JSON_EXTRACT()) for maximum compatibility "JSON_UNQUOTE(JSON_EXTRACT(#{table_column}, '$.#{json_key}'))" when /sqlite/ # SQLite returns JSON booleans as integers (0/1), unlike ->> on # PostgreSQL/MySQL which return text. CAST keeps the adapters in sync. "CAST(json_extract(#{table_column}, '$.#{json_key}') AS TEXT)" else # Fallback to PostgreSQL syntax for unknown adapters Rails.logger.warn("Unknown database adapter '#{adapter}' for JSON extraction. Falling back to PostgreSQL syntax.") "#{table_column} ->> '#{json_key}'" end end |