Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion console1984.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Gem::Specification.new do |spec|

spec.add_dependency 'rainbow'
spec.add_dependency 'parser'
spec.add_dependency 'rails', '>= 7.0'
spec.add_dependency 'rails', '>= 6.0'
spec.add_dependency 'irb', '~> 1.13'

spec.add_development_dependency 'benchmark-ips'
Expand Down
2 changes: 2 additions & 0 deletions lib/console1984.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
require 'console1984/engine'
require_relative 'console1984/patches'
Console1984::Patches.apply_all!

require "zeitwerk"
class_loader = Zeitwerk::Loader.for_gem
Expand Down
14 changes: 14 additions & 0 deletions lib/console1984/patches.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require_relative 'patches/active_support_extensions'
require_relative 'patches/active_record_migration_patch'
require_relative 'patches/active_record_encryption_patch'

module Console1984
module Patches
def self.apply_all!
ActiveSupportExtensions.apply!
ActiveRecordMigrationPatch.apply!
# ActiveRecordEncryptionPatch.apply!
end
end
end

59 changes: 59 additions & 0 deletions lib/console1984/patches/active_record_encryption_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# lib/console1984/patches/active_record_encryption_patch.rb

module Console1984
module Patches
module ActiveRecordEncryptionPatch
def self.included(base)
base.extend(ClassMethods)

# Add debug method to help troubleshoot issues
base.define_singleton_method(:debug_encryption) do
puts "ActiveRecord encryption patch is active"
end
end

module ClassMethods
# More robust implementation of the 'encrypts' method for Rails 6
def encrypts(*attributes, **options)
if defined?(ActiveRecord::Encryption) && respond_to?(:encrypts, true)
# If we're on Rails 7+, use the native implementation
super
else
# For Rails 6, implement a simplified version
require 'attr_encrypted' rescue nil

if defined?(AttrEncrypted)
# Use attr_encrypted if available
attributes.each do |attribute|
attr_encrypted_options = {
key: options[:key] || SecureRandom.hex(16),
algorithm: options[:algorithm] || 'aes-256-gcm'
}

attr_encrypted attribute, attr_encrypted_options
end
else
# Fallback to simple accessors if attr_encrypted isn't available
attributes.each do |attribute|
# Create regular accessors as a fallback
attr_accessor attribute unless method_defined?(attribute)

# Add metadata methods expected by the gem
define_singleton_method("#{attribute}_encrypted?") { true }
end

# Log the fallback for debugging
Rails.logger.warn "Using fallback encryption for #{attributes.join(', ')}. Install attr_encrypted gem for better security."
end
end
end
end

def self.apply!
if Rails.gem_version < Gem::Version.new('7.0')
ActiveRecord::Base.include self
end
end
end
end
end
38 changes: 38 additions & 0 deletions lib/console1984/patches/active_record_migration_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# lib/console1984/patches/active_record_migration_patch.rb

module Console1984
module Patches
module ActiveRecordMigrationPatch
def migration_context
original_migration_context = super

# Monkey patch the migration context to accept Rails 7.0 migrations
if Rails.version.to_f < 7.0
migration_context_class = original_migration_context.class

unless migration_context_class.method_defined?(:parse_migration_version_with_rails7_support)
migration_context_class.class_eval do
alias_method :parse_migration_version_without_rails7_support, :parse_migration_version

def parse_migration_version_with_rails7_support(version)
# If the migration version is 7.0, downgrade it to 6.0 for compatibility
version = "6.0" if version == "7.0"
parse_migration_version_without_rails7_support(version)
end

alias_method :parse_migration_version, :parse_migration_version_with_rails7_support
end
end
end

original_migration_context
end

def self.apply!
if Rails.gem_version < Gem::Version.new('7.0')
ActiveRecord::MigrationContext.prepend self
end
end
end
end
end
94 changes: 94 additions & 0 deletions lib/console1984/patches/active_support_extensions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# lib/console1984/patches/active_support_extensions.rb

module Console1984
module Patches
module ActiveSupportExtensions
module MattrDefaultPatch
# Regular class-level attribute accessors
def mattr_reader(*syms, **options)
if options.key?(:default)
default_value = options.delete(:default)
result = super(*syms, **options)

if syms.size == 1
var_name = syms.first
class_var = "@@#{var_name}"

if class_variable_defined?(class_var) && class_variable_get(class_var).nil?
class_variable_set(class_var, default_value)
end
end

result
else
super
end
end

def mattr_accessor(*syms, **options)
if options.key?(:default)
default_value = options.delete(:default)
result = super(*syms, **options)

if syms.size == 1
var_name = syms.first
class_var = "@@#{var_name}"

if class_variable_defined?(class_var) && class_variable_get(class_var).nil?
class_variable_set(class_var, default_value)
end
end

result
else
super
end
end
end

module ThreadMattrDefaultPatch
# Thread-specific attribute accessors
def thread_mattr_reader(*syms, **options)
if options.key?(:default)
default_value = options.delete(:default)
result = super(*syms, **options)

if syms.size == 1
var_name = syms.first
# For thread-specific attributes, we need to set the default in the current thread
Thread.current["#{self.name}::#{var_name}"] ||= default_value
end

result
else
super
end
end

def thread_mattr_accessor(*syms, **options)
if options.key?(:default)
default_value = options.delete(:default)
result = super(*syms, **options)

if syms.size == 1
var_name = syms.first
# For thread-specific attributes, we need to set the default in the current thread
Thread.current["#{self.name}::#{var_name}"] ||= default_value
end

result
else
super
end
end
end

def self.apply!
if Rails.gem_version < Gem::Version.new('6.1')
Module.prepend MattrDefaultPatch
Module.prepend ThreadMattrDefaultPatch
end
end
end
end
end