stratagem 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. data/LICENSE +29 -0
  2. data/Manifest +40 -38
  3. data/Rakefile +3 -3
  4. data/lib/stratagem.rb +22 -7
  5. data/lib/stratagem/authentication.rb +2 -1
  6. data/lib/stratagem/auto_mock/aquifer.rb +88 -15
  7. data/lib/stratagem/auto_mock/factory.rb +19 -30
  8. data/lib/stratagem/auto_mock/value_generator.rb +3 -1
  9. data/lib/stratagem/client.rb +3 -2
  10. data/lib/stratagem/crawler/authentication.rb +10 -3
  11. data/lib/stratagem/crawler/form.rb +2 -2
  12. data/lib/stratagem/crawler/html_utils.rb +12 -1
  13. data/lib/stratagem/crawler/parameter_resolver.rb +18 -4
  14. data/lib/stratagem/crawler/route_invoker.rb +58 -16
  15. data/lib/stratagem/crawler/session.rb +13 -5
  16. data/lib/stratagem/crawler/site_model.rb +20 -8
  17. data/lib/stratagem/extensions/object.rb +2 -2
  18. data/lib/stratagem/extensions/string.rb +2 -2
  19. data/lib/stratagem/instrumentation.rb +18 -0
  20. data/lib/stratagem/{framework_extensions → instrumentation}/method_invocation.rb +1 -1
  21. data/lib/stratagem/instrumentation/models.rb +25 -0
  22. data/lib/stratagem/instrumentation/models/annotations.rb +114 -0
  23. data/lib/stratagem/instrumentation/models/association.rb +40 -0
  24. data/lib/stratagem/instrumentation/models/authentication.rb +7 -0
  25. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/authlogic/detect.rb +2 -2
  26. data/lib/stratagem/instrumentation/models/authentication/authlogic/instrumentation.rb +13 -0
  27. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/authlogic/metadata.rb +1 -3
  28. data/lib/stratagem/instrumentation/models/authentication/devise/detect.rb +11 -0
  29. data/lib/stratagem/instrumentation/models/authentication/devise/instrumentation.rb +18 -0
  30. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/devise/metadata.rb +7 -3
  31. data/lib/stratagem/{framework_extensions/models/adapters/util/authentication_metadata.rb → instrumentation/models/authentication/metadata.rb} +2 -2
  32. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/restful_authentication/detect.rb +2 -4
  33. data/lib/stratagem/{framework_extensions/models/adapters/restful_authentication/extensions.rb → instrumentation/models/authentication/restful_authentication/instrumentation.rb} +1 -1
  34. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/authentication}/restful_authentication/metadata.rb +2 -2
  35. data/lib/stratagem/{framework_extensions → instrumentation}/models/detect.rb +1 -1
  36. data/lib/stratagem/{framework_extensions → instrumentation}/models/metadata.rb +6 -4
  37. data/lib/stratagem/{framework_extensions → instrumentation}/models/mocking.rb +1 -1
  38. data/lib/stratagem/instrumentation/models/persistence.rb +9 -0
  39. data/lib/stratagem/instrumentation/models/persistence/active_record/detect.rb +18 -0
  40. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/active_record/extensions.rb +5 -1
  41. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/active_record/metadata.rb +25 -9
  42. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/active_record/tracing.rb +4 -2
  43. data/lib/stratagem/instrumentation/models/persistence/common/detect.rb +7 -0
  44. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/common/extensions.rb +0 -0
  45. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/persistence}/common/metadata.rb +6 -2
  46. data/lib/stratagem/instrumentation/models/persistence/common/tracing.rb +4 -0
  47. data/lib/stratagem/instrumentation/models/support_libraries.rb +7 -0
  48. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/support_libraries}/friendly_id/detect.rb +2 -2
  49. data/lib/stratagem/{framework_extensions/models/adapters → instrumentation/models/support_libraries}/friendly_id/metadata.rb +2 -2
  50. data/lib/stratagem/instrumentation/models/support_libraries/state_machine/detect.rb +11 -0
  51. data/lib/stratagem/instrumentation/models/support_libraries/state_machine/metadata.rb +17 -0
  52. data/lib/stratagem/{framework_extensions → instrumentation}/models/tracing.rb +2 -2
  53. data/lib/stratagem/{framework_extensions → instrumentation}/rails.rb +0 -0
  54. data/lib/stratagem/{framework_extensions → instrumentation}/rails2/action_controller.rb +0 -0
  55. data/lib/stratagem/{framework_extensions → instrumentation}/rails2/action_mailer.rb +0 -0
  56. data/lib/stratagem/{framework_extensions → instrumentation}/rails3/parameters.rb +0 -0
  57. data/lib/stratagem/{framework_extensions → instrumentation}/request_forgery_protection.rb +0 -0
  58. data/lib/stratagem/model/application.rb +30 -15
  59. data/lib/stratagem/model/components/controller.rb +2 -2
  60. data/lib/stratagem/model/components/reference.rb +2 -2
  61. data/lib/stratagem/model/components/view.rb +1 -1
  62. data/lib/stratagem/model_builder.rb +19 -8
  63. data/lib/stratagem/scanner.rb +1 -1
  64. data/lib/stratagem/site_crawler.rb +4 -2
  65. data/stratagem.gemspec +7 -7
  66. data/templates/install/tasks/stratagem.rake +9 -1
  67. metadata +86 -82
  68. data/lib/stratagem/framework_extensions.rb +0 -18
  69. data/lib/stratagem/framework_extensions/models.rb +0 -21
  70. data/lib/stratagem/framework_extensions/models/adapters/active_record/detect.rb +0 -7
  71. data/lib/stratagem/framework_extensions/models/adapters/authlogic/extensions.rb +0 -10
  72. data/lib/stratagem/framework_extensions/models/adapters/authlogic/tracing.rb +0 -4
  73. data/lib/stratagem/framework_extensions/models/adapters/common/detect.rb +0 -7
  74. data/lib/stratagem/framework_extensions/models/adapters/common/tracing.rb +0 -4
  75. data/lib/stratagem/framework_extensions/models/adapters/devise/detect.rb +0 -11
  76. data/lib/stratagem/framework_extensions/models/adapters/devise/extensions.rb +0 -0
  77. data/lib/stratagem/framework_extensions/models/adapters/devise/tracing.rb +0 -4
  78. data/lib/stratagem/framework_extensions/models/adapters/friendly_id/extensions.rb +0 -0
  79. data/lib/stratagem/framework_extensions/models/adapters/friendly_id/tracing.rb +0 -4
  80. data/lib/stratagem/framework_extensions/models/adapters/restful_authentication/tracing.rb +0 -4
  81. data/lib/stratagem/framework_extensions/models/annotations.rb +0 -78
@@ -1,4 +1,4 @@
1
- module Stratagem::ApplicationExtensions
1
+ module Stratagem::Instrumentation
2
2
  class MethodInvocation
3
3
  attr_accessor :method, :controller_path, :controller_action, :line_number, :model_instance, :model_class, :stack_trace, :args, :type
4
4
 
@@ -0,0 +1,25 @@
1
+ module Stratagem::Instrumentation::Models; end
2
+ module Stratagem::Instrumentation::Models::Adapters; end
3
+
4
+ require 'stratagem/instrumentation/models/mocking'
5
+ require 'stratagem/instrumentation/models/metadata'
6
+ require 'stratagem/instrumentation/models/tracing'
7
+ require 'stratagem/instrumentation/models/annotations'
8
+ require 'stratagem/instrumentation/models/detect'
9
+
10
+ require 'stratagem/instrumentation/models/persistence'
11
+ require 'stratagem/instrumentation/models/authentication'
12
+ require 'stratagem/instrumentation/models/support_libraries'
13
+
14
+ # base = File.join(File.dirname(__FILE__), 'models', 'persistence', 'util')
15
+ # Dir.entries(base).select {|s| s =~ /\.rb$/}.each {|helper|
16
+ # require File.join(base, helper.gsub(/\.rb/, ''))
17
+ # }
18
+ #
19
+ # base = File.join(File.dirname(__FILE__), 'models', 'persistence')
20
+ # Dir.entries(base).select {|s| s !~ /^\./ && s != 'util' }.each {|adapter_dir|
21
+ # require File.join(base, adapter_dir, 'detect')
22
+ # require File.join(base, adapter_dir, 'tracing')
23
+ # require File.join(base, adapter_dir, 'metadata')
24
+ # require File.join(base, adapter_dir, 'extensions')
25
+ # }
@@ -0,0 +1,114 @@
1
+ # Defines the stratagem namespace attached to the model
2
+ module Stratagem::Instrumentation::Models
3
+ ValidatorDefinition = Struct.new(:validation, :field, :args, :model_class)
4
+
5
+ class InstanceAnnotations
6
+ include Mocking
7
+
8
+ def initialize(object)
9
+ @object = object
10
+ end
11
+
12
+ def method_missing(method, *args, &block)
13
+ @object.class.stratagem.send(method, *args, &block)
14
+ end
15
+ end
16
+
17
+ class Annotations
18
+ include Metadata
19
+ include Tracing
20
+
21
+ attr_reader :model
22
+
23
+ AdapterDescriptor = Struct.new(:metadata, :detector, :tracing, :instrumentation)
24
+
25
+ class << self
26
+ def configure(model)
27
+ puts "configuring #{model.name}"
28
+
29
+ # add the stratagem namespace
30
+ model.class_eval do
31
+ def self.stratagem
32
+ # one stratagem instance per subclass
33
+ @@stratagem ||= {}
34
+ @@stratagem[self] ||= Stratagem::Instrumentation::Models::Annotations.new(self)
35
+ end
36
+
37
+
38
+ def stratagem
39
+ @stratagem ||= Stratagem::Instrumentation::Models::InstanceAnnotations.new(self)
40
+ end
41
+ end
42
+
43
+ # connect the adapters
44
+ detect_adapters(model).each {|adapter|
45
+ if adapter.detector.supports?(model)
46
+ puts "#{model.name} supports #{adapter.tracing.name}"
47
+ model.send(:include, adapter.tracing)
48
+ end
49
+ }
50
+ end
51
+
52
+ def detect_adapters(model)
53
+ Detect.sg_subclasses.map do |detector|
54
+ namespace = detector.name.split('::')
55
+ namespace.pop
56
+ namespace = namespace.join('::')
57
+ instrumentation = module_class_ref(namespace+"::Instrumentation")
58
+ tracing = module_class_ref(namespace+"::Tracing")
59
+ metadata = module_class_ref(namespace+"::Metadata")
60
+ metadata = metadata.new(model) if metadata
61
+ AdapterDescriptor.new(metadata, detector, tracing, instrumentation)
62
+ end
63
+ end
64
+
65
+ def module_class_ref(name)
66
+ begin
67
+ module_eval(name)
68
+ rescue Exception
69
+ nil
70
+ end
71
+ end
72
+
73
+
74
+ end
75
+
76
+ def initialize(model)
77
+ puts "initializing stratagem for #{model.name} - #{self.class.name}"
78
+ @model = model
79
+ self.class.detect_adapters(model).each do |adapter|
80
+ if adapter.detector.supports?(model)
81
+ # puts "\t#{model.name} supports #{adapter.detector.name}"
82
+ instrument_model(adapter)
83
+ # else
84
+ # puts "#{model.name} does not support #{adapter.detector.name}"
85
+ end
86
+ end
87
+ rescue
88
+ puts $!.message
89
+ puts $!.backtrace
90
+ end
91
+
92
+ def instrument_model(adapter)
93
+ instrument_model_with(adapter.tracing)
94
+ instrument_model_with(adapter.instrumentation)
95
+ end
96
+
97
+ def instrument_model_with(instrumentation)
98
+ return if instrumentation.nil?
99
+
100
+ unless model.ancestors.include?(instrumentation)
101
+ puts "including #{instrumentation.name} in #{model.name}"
102
+ model.send(:include, instrumentation)
103
+ end
104
+ end
105
+
106
+ def adapters
107
+ # supported adapters may change throughout the lifecycle of a class / object
108
+ @adapters ||= self.class.detect_adapters(model)
109
+ end
110
+
111
+
112
+ end
113
+
114
+ end
@@ -0,0 +1,40 @@
1
+ module Stratagem::Instrumentation::Models
2
+ class Association
3
+ attr_reader :from_class, :name, :foreign_key, :macro, :options
4
+
5
+ def initialize(from_class, name, foreign_key, klass, macro, options)
6
+ @from_class = from_class
7
+ @name = name
8
+ @foreign_key = foreign_key
9
+ @klass = klass
10
+ @macro = macro
11
+ @options = options
12
+ end
13
+
14
+ def klass
15
+ if (@klass.kind_of?(String))
16
+ if (options[:polymorphic])
17
+ @poly_count ||= 0
18
+
19
+ # all possibilities
20
+ possible_classes = ActiveRecord::Base.sg_subclasses.sort {|a,b| a.name <=> b.name }.select do |sc|
21
+ sc.stratagem.relations(:has_many).find {|r| r.klass == from_class } != nil
22
+ end
23
+
24
+ if (possible_classes.size > 0)
25
+ @poly_count += 1
26
+ @poly_count = 1 if @poly_count > possible_classes.size
27
+ return possible_classes[@poly_count-1]
28
+ else
29
+ return nil
30
+ end
31
+ else
32
+ # unknown why the class could not be loaded
33
+ return nil
34
+ end
35
+ else
36
+ return @klass
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,7 @@
1
+ module Stratagem::Instrumentation::Models::Authentication; end
2
+
3
+ pattern = File.join(File.dirname(__FILE__), 'authentication', '**', '*.rb')
4
+ Dir.glob(pattern).each {|filename|
5
+ require filename
6
+ }
7
+
@@ -1,5 +1,5 @@
1
- module Stratagem::ApplicationExtensions::Models::Adapters::Authlogic
2
- class Detect < Stratagem::ApplicationExtensions::Models::Detect
1
+ module Stratagem::Instrumentation::Models::Authentication::Authlogic
2
+ class Detect < Stratagem::Instrumentation::Models::Detect
3
3
  def self.supports?(model)
4
4
  begin
5
5
  model.ancestors.include?(::Authlogic::ActsAsAuthentic::MagicColumns::Methods)
@@ -0,0 +1,13 @@
1
+ module Stratagem::Instrumentation::Models::Authentication::Authlogic
2
+ module Instrumentation
3
+ def self.included(model)
4
+ model.class_eval do
5
+ before_save { |record|
6
+ if record.attribute_names.include?('active')
7
+ record.active = true
8
+ end
9
+ }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,9 +1,7 @@
1
- module Stratagem::ApplicationExtensions::Models::Adapters::Authlogic
1
+ module Stratagem::Instrumentation::Models::Authentication::Authlogic
2
2
 
3
3
  # prefix method names with to avoid collision
4
4
  class Metadata
5
- include Stratagem::ApplicationExtensions::Models::Adapters::Common::AuthenticationMetadata
6
-
7
5
  VIRTUAL_COLUMNS = [:password, :password_confirmation]
8
6
 
9
7
  def authenticates?
@@ -0,0 +1,11 @@
1
+ module Stratagem::Instrumentation::Models::Authentication::Devise
2
+ class Detect < Stratagem::Instrumentation::Models::Detect
3
+ def self.supports?(model)
4
+ begin
5
+ model.ancestors.find {|a| a.name.include? 'Devise::Models' } != nil
6
+ rescue
7
+ false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ module Stratagem::Instrumentation::Models::Authentication::Devise
2
+ module Instrumentation
3
+ def self.included(model)
4
+ model.class_eval do
5
+ before_save { |record|
6
+ if record.attribute_names.include?('active')
7
+ puts "activating user"
8
+ record.active = true
9
+ end
10
+ }
11
+
12
+ after_save {|record|
13
+ p record
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,9 +1,13 @@
1
- module Stratagem::ApplicationExtensions::Models::Adapters::Devise
1
+ module Stratagem::Instrumentation::Models::Authentication::Devise
2
2
 
3
3
  # prefix method names with to avoid collision
4
4
  class Metadata
5
- include Stratagem::ApplicationExtensions::Models::Adapters::Common::AuthenticationMetadata
6
-
5
+ begin
6
+ include Stratagem::Instrumentation::Models::Authentication::Metadata
7
+ rescue
8
+ puts $!.message
9
+ end
10
+
7
11
  VIRTUAL_COLUMNS = [:password, :password_confirmation]
8
12
 
9
13
  def authenticates?
@@ -1,7 +1,7 @@
1
- module Stratagem::ApplicationExtensions::Models::Adapters::Common
1
+ module Stratagem::Instrumentation::Models::Authentication
2
2
 
3
3
  # prefix method names with to avoid collision
4
- module AuthenticationMetadata
4
+ module Metadata
5
5
  def exclude_attributes_for_mocking
6
6
  # open id
7
7
  attrs = @model.stratagem.attribute_names.select {|a|
@@ -1,7 +1,5 @@
1
-
2
-
3
- module Stratagem::ApplicationExtensions::Models::Adapters::RestfulAuthentication
4
- class Detect < Stratagem::ApplicationExtensions::Models::Detect
1
+ module Stratagem::Instrumentation::Models::Authentication::RestfulAuthentication
2
+ class Detect < Stratagem::Instrumentation::Models::Detect
5
3
  def self.supports?(model)
6
4
  begin
7
5
  model.ancestors.include?(::Authentication::ByPassword)
@@ -1,5 +1,5 @@
1
1
  if (defined?(Authentication))
2
- Authentication.subclasses.each do |model|
2
+ Authentication.sg_subclasses.each do |model|
3
3
  model.class_eval do
4
4
  # add support for aasm models
5
5
  before_save { |record|
@@ -1,8 +1,8 @@
1
- module Stratagem::ApplicationExtensions::Models::Adapters::RestfulAuthentication
1
+ module Stratagem::Instrumentation::Models::Authentication::RestfulAuthentication
2
2
 
3
3
  # prefix method names with to avoid collision
4
4
  class Metadata
5
- include Stratagem::ApplicationExtensions::Models::Adapters::Common::AuthenticationMetadata
5
+ include Stratagem::Instrumentation::Models::Authentication::Metadata
6
6
 
7
7
  VIRTUAL_COLUMNS = [:password, :password_confirmation]
8
8
 
@@ -1,4 +1,4 @@
1
- module Stratagem::ApplicationExtensions::Models
1
+ module Stratagem::Instrumentation::Models
2
2
  class Detect
3
3
  def self.supports?(model)
4
4
  false
@@ -1,8 +1,6 @@
1
1
 
2
- module Stratagem::ApplicationExtensions::Models
2
+ module Stratagem::Instrumentation::Models
3
3
  module Metadata
4
- StratagemAssociation = Struct.new(:name, :foreign_key, :klass, :macro, :options)
5
-
6
4
  INSTANCE_ENUMERATION_METHODS = [:relations, :attribute_names, :ignore_attributes, :internal_attributes, :unaccessible_attributes, :invalid_columns, :exclude_attributes_for_mocking]
7
5
  INSTANCE_ENTITY_METHODS = [:attribute_type, :column_from_error, :authenticates?, :whitelists_attributes?, :blacklists_attributes?]
8
6
 
@@ -27,6 +25,10 @@ module Stratagem::ApplicationExtensions::Models
27
25
 
28
26
  # Convenience methods
29
27
 
28
+ def subclasses?
29
+ model.sg_subclasses().size > 0
30
+ end
31
+
30
32
  def foreign_keys
31
33
  relations(:belongs_to).map {|relation| relation.foreign_key }
32
34
  end
@@ -75,7 +77,7 @@ module Stratagem::ApplicationExtensions::Models
75
77
  memory
76
78
  rescue
77
79
  puts "error running callbacks: #{$!.message}"
78
- puts $!.backtrace
80
+ #puts $!.backtrace
79
81
  end
80
82
  }
81
83
  (results || []).flatten.compact.uniq
@@ -1,4 +1,4 @@
1
- module Stratagem::ApplicationExtensions::Models
1
+ module Stratagem::Instrumentation::Models
2
2
  module Mocking
3
3
  def mock_attributes
4
4
  @attributes ||= {}
@@ -0,0 +1,9 @@
1
+ module Stratagem::Instrumentation::Models::Persistence; end
2
+
3
+ base = File.join(File.dirname(__FILE__), 'persistence')
4
+ Dir.entries(base).select {|s| s !~ /^\./ && s != 'util' }.each {|adapter_dir|
5
+ require File.join(base, adapter_dir, 'detect')
6
+ require File.join(base, adapter_dir, 'tracing')
7
+ require File.join(base, adapter_dir, 'metadata')
8
+ require File.join(base, adapter_dir, 'extensions')
9
+ }
@@ -0,0 +1,18 @@
1
+ module Stratagem::Instrumentation::Models::Persistence::ActiveRecord
2
+ class Detect < Stratagem::Instrumentation::Models::Detect
3
+ IGNORE_CLASSES = ['ldap']
4
+
5
+ def self.supports?(model)
6
+ if model.ancestors.include?(ActiveRecord::Base)
7
+ if IGNORE_CLASSES.find {|ic| model.name.downcase.include?(ic) }
8
+ puts "Ignoring class: #{model.name}"
9
+ false
10
+ else
11
+ true
12
+ end
13
+ else
14
+ false
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,9 @@
1
1
  class ActiveRecord::Base
2
2
  class << self
3
+ def existing_instance_ids
4
+ find_by_sql("select id from #{table_name}").map {|i| i.id }
5
+ end
6
+
3
7
  def removed_methods=(methods)
4
8
  @@removed_methods = methods
5
9
  end
@@ -13,7 +17,7 @@ class ActiveRecord::Base
13
17
  end
14
18
  end
15
19
 
16
- Stratagem::ApplicationExtensions::Models::Annotations.configure(self)
20
+ Stratagem::Instrumentation::Models::Annotations.configure(self)
17
21
 
18
22
  end
19
23
 
@@ -1,20 +1,27 @@
1
- module Stratagem::ApplicationExtensions::Models::Adapters::ActiveRecord
2
-
3
- # prefix method names with to avoid collision
1
+ module Stratagem::Instrumentation::Models::Persistence::ActiveRecord
4
2
  class Metadata
5
-
6
3
  attr_reader :model, :instance
7
4
 
8
5
  def initialize(model)
9
6
  @model = model
10
- @instance = @model.new unless (@model == ActiveRecord::Base)
7
+ begin
8
+ @instance = @model.new unless (@model == ActiveRecord::Base)
9
+ rescue
10
+ puts "ERROR: #{@model.name} could not be instantiated: #{$!.message}"
11
+ end
11
12
  end
12
13
 
13
14
  def relations(relation_type=nil) # :belongs_to, :has_many
14
15
  @relations ||= {}
15
16
  @relations[relation_type || :all] ||= model.reflect_on_all_associations(relation_type).map {|a|
17
+ klass = begin
18
+ a.klass # may fail if it's a polymorphic association
19
+ rescue
20
+ a.class_name
21
+ end
22
+
16
23
  begin
17
- Stratagem::ApplicationExtensions::Models::Metadata::StratagemAssociation.new(a.name.to_sym, a.association_foreign_key.to_sym, a.klass, a.macro, a.options)
24
+ Stratagem::Instrumentation::Models::Association.new(model, a.name.to_sym, a.association_foreign_key.to_sym, klass, a.macro, a.options)
18
25
  rescue
19
26
  puts "ERROR: #{$!.message}"
20
27
  end
@@ -34,9 +41,18 @@ module Stratagem::ApplicationExtensions::Models::Adapters::ActiveRecord
34
41
  # this is typically a not null enforced by the database but not
35
42
  # by the model
36
43
  def column_from_error(database_error)
37
- if (database_error.kind_of?(Mysql::Error) || database_error.kind_of?(::ActiveRecord::StatementInvalid))
38
- database_error.message =~ /Column '(.*)?' cannot/
39
- $1 ? $1.to_sym : nil
44
+ puts "COLUMN FROM ERROR:"
45
+ puts database_error.message
46
+ puts database_error.class
47
+ if (database_error.message.downcase.include?('column ') || database_error.kind_of?(::ActiveRecord::StatementInvalid))
48
+ database_error.message =~ /column (.*?\s)/i
49
+ if ($1)
50
+ column = $1
51
+ column.gsub!(/^.*?\./, '').gsub!(/\s.*/, '')
52
+ column
53
+ else
54
+ nil
55
+ end
40
56
  else
41
57
  puts database_error.class.name
42
58
  nil