stepford 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -125,6 +125,36 @@ Check ActiveRecord circular dependencies:
125
125
 
126
126
  bundle exec stepford circular
127
127
 
128
+ Then it outputs the circular dependencies, e.g.:
129
+
130
+ The following non-nullable foreign keys used in ActiveRecord model associations are involved in circular dependencies:
131
+
132
+ foo.bar_id -> bar.bartender_id -> bartender.sandwich_id -> sandwich.foo_id
133
+
134
+ foo.bar_id -> bar.waiter_id -> waiter.waitress_id
135
+
136
+ waitress.waiter_id -> bar.waiter_id -> waiter.waitress_id
137
+
138
+ ...
139
+
140
+ Distinct foreign keys involved in a circular dependency:
141
+
142
+ bar.bartender_id
143
+ bar.waiter_id
144
+ bartender.sandwich_id
145
+ foo.bar_id
146
+ sandwich.foo_id
147
+ waiter.waitress_id
148
+ waitress.waiter_id
149
+
150
+ Foreign keys by number of circular dependency chains involved with:
151
+
152
+ 3 (out of 6): bar.bartender_id -> bartender
153
+ 2 (out of 6): bar.waiter_id -> waiter
154
+ 1 (out of 6): bartender.sandwich_id -> sandwich
155
+ 1 (out of 6): foo.bar_id -> bar
156
+ ...
157
+
128
158
  ##### Factories
129
159
 
130
160
  ###### Creating Factories
@@ -26,24 +26,34 @@ module Stepford
26
26
  check_associations(model_class)
27
27
  end
28
28
 
29
- puts "Circles of shame:"
29
+ puts "The following non-nullable foreign keys used in ActiveRecord model associations are involved in circular dependencies:"
30
30
  @@circles.sort.each do |c|
31
31
  puts
32
32
  puts "#{c}"
33
33
  end
34
34
  puts
35
35
  puts
36
- puts "All foreign keys involved in a circular dependency:"
36
+ puts "Distinct foreign keys involved in a circular dependency:"
37
37
  puts
38
38
  @@offenders.sort.each do |c|
39
39
  puts "#{c[0]}.#{c[1]}"
40
40
  end
41
+
42
+ totals = {}
43
+ @@circles_sorted.each do |arr|
44
+ arr.each do |key|
45
+ totals[key] = 0 unless totals[key]
46
+ totals[key] = totals[key] + 1
47
+ end
48
+ end
41
49
  puts
42
50
  puts
43
- puts "Arbitrarily chosen foreign_keys involved in a circular dependency that would break each circular dependency chain if marked as nullable. It would be a better idea to examine the full list of foreign keys and circles above, fix, then rerun:"
51
+ puts "Foreign keys by number of circular dependency chains involved with:"
44
52
  puts
45
- @@selected_offenders.sort.each do |c|
46
- puts "#{c[0]}.#{c[1]}"
53
+ totals.sort_by {|k,v| v}.reverse.each do |arr|
54
+ c = arr[0]
55
+ t = arr[1]
56
+ puts "#{t} (out of #{@@circles_sorted.size}): #{c[0]}.#{c[1]} -> #{c[2]}"
47
57
  end
48
58
 
49
59
  return (@@offenders.size == 0)
@@ -51,18 +61,19 @@ module Stepford
51
61
 
52
62
  def self.check_associations(model_class)
53
63
  @@level += 1
54
-
64
+
55
65
  model_class.reflections.collect {|association_name, reflection|
56
66
  @@model_and_association_names = [] if @@level == 1
57
67
  next unless reflection.macro == :belongs_to
58
68
  assc_sym = reflection.name.to_sym
59
69
  clas_sym = reflection.class_name.underscore.to_sym
70
+ next_class = clas_sym.to_s.camelize.constantize
60
71
 
61
72
  # if has a foreign key, then if NOT NULL or is a presence validate, the association is required and should be output. unfortunately this could mean a circular reference that will have to be manually fixed
62
73
  has_presence_validator = model_class.validators_on(assc_sym).collect{|v|v.class}.include?(ActiveModel::Validations::PresenceValidator)
63
74
  required = reflection.foreign_key ? (has_presence_validator || model_class.columns.any?{|c| !c.null && c.name.to_sym == reflection.foreign_key.to_sym}) : false
64
75
  if required
65
- key = [model_class.to_s.underscore.to_sym, assc_sym]
76
+ key = [model_class.table_name.to_sym, reflection.foreign_key.to_sym, next_class.table_name]
66
77
  if @@model_and_association_names.include?(key)
67
78
  @@offenders << @@model_and_association_names.last unless @@offenders.include?(@@model_and_association_names.last)
68
79
  short = @@model_and_association_names.dup
@@ -71,13 +82,11 @@ module Stepford
71
82
  sorted = short.sort
72
83
  unless @@circles_sorted.include?(sorted)
73
84
  @@circles_sorted << sorted
74
- last_key_in_circle_before_restart = short.last
75
- @@selected_offenders << last_key_in_circle_before_restart unless @@selected_offenders.include?(last_key_in_circle_before_restart)
76
85
  @@circles << "#{(short << key).collect{|b|"#{b[0]}.#{b[1]}"}.join(' -> ')}".to_sym
77
86
  end
78
87
  else
79
88
  @@model_and_association_names << key
80
- check_associations(reflection.class_name.constantize)
89
+ check_associations(next_class)
81
90
  end
82
91
  end
83
92
  }
@@ -1,3 +1,3 @@
1
1
  module Stepford
2
- VERSION = '0.9.1'
2
+ VERSION = '0.9.2'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stepford
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: