stratagem 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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