flatten_record 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3f11d8fa55541889fa6fdcce3dbf9ab49a3e80d1
4
- data.tar.gz: fe9feffcbd9da172e4922a8b413451e2bedbe8f5
3
+ metadata.gz: b3f760e4ba28e47a8cb7e46621300db8c99d36c9
4
+ data.tar.gz: 4129c16a709afbd09567ee9ce888257651f20a19
5
5
  SHA512:
6
- metadata.gz: cd1c791340df638d6e41d4800a3b0ba838df3b3c07f4b91c0902167e7571401097af71e2962658aa29e4b2666743e80c4be2a7c6377c3d67b7c7c1160d0b84ea
7
- data.tar.gz: d7a6093c910fffcd069b442d3f4dc3e494383db65341de9c497fdaf4c6fcc4b3eaab674f9f73c3d218e82daacfd781f33c5d1d63e2b360dd9accd85c35768dba
6
+ metadata.gz: 5713c428677377b05b1feb93bc50fa821c173e6ccc33a52c6c571e1731c495d372b4f9006920d4ef811686b8d990ee6ef2f513f3efa3a9861e1d88fc71f851ba
7
+ data.tar.gz: 3ea39337ec9243801d6883bf1831267e3bbb28f70f6bf6af543dd8684e19ea7a4456e9c3c4029e2c507901d43900ba149525f9c94fa2c72e27148c8951a5cf2f
@@ -45,21 +45,13 @@ module FlattenRecord
45
45
 
46
46
  protected
47
47
  def validate_except(attrs)
48
- attrs.each do |attr|
49
- error = "unknown attribute '#{attr}' in #{@target_model.name.to_s}"
50
- @errors << error unless target_method?(attr)
51
- @except << attr
52
- end
48
+ validate_attrs(:except, attrs)
53
49
  end
54
50
 
55
51
  def validate_only(attrs)
56
- attrs.each do |attr|
57
- error = "unknown attribute '#{attr}' in #{@target_model.name.to_s}"
58
- @errors << error unless target_method?(attr)
59
- @only << attr
60
- end
52
+ validate_attrs(:only, attrs)
61
53
  end
62
-
54
+
63
55
  def validate_methods(methods)
64
56
  methods.each do |method, type|
65
57
  error = "undefined method '#{method}' in #{@target_model.name}"
@@ -92,6 +84,19 @@ module FlattenRecord
92
84
  end
93
85
 
94
86
  private
87
+ def validate_attrs(name, attrs)
88
+ attrs.each do |attr|
89
+ error = "unknown attribute '#{attr}' in #{@target_model.name.to_s}"
90
+ @errors << error unless target_method?(attr)
91
+ case name
92
+ when :only
93
+ @only << attr
94
+ when :except
95
+ @except << attr
96
+ end
97
+ end
98
+ end
99
+
95
100
  def model_method?(method)
96
101
  @model.attribute_method?(method) ||
97
102
  @model.method_defined?(method)
@@ -2,8 +2,7 @@ module FlattenRecord
2
2
  module Meta
3
3
  class IdColumn < Column
4
4
  def initialize(parent, primary_key, target_model, model)
5
- @column = primary_key
6
- super(parent, @column, target_model, model)
5
+ super(parent, primary_key, target_model, model)
7
6
  end
8
7
 
9
8
  def name
@@ -7,12 +7,8 @@ module FlattenRecord
7
7
  end
8
8
 
9
9
  def all_columns
10
- return @columns if @columns
11
- child_columns = @include.values.collect do |n|
12
- n[:columns] + n[:methods] + n[:compute]
13
- end
14
- child_columns.flatten!
15
- @columns = @base_columns + @methods + @compute + child_columns
10
+ child_columns = @include.values.collect(&:all_columns)
11
+ @base_columns + @methods + @compute + child_columns.flatten
16
12
  end
17
13
 
18
14
  def associated_models
@@ -59,22 +55,27 @@ module FlattenRecord
59
55
 
60
56
  def build(definition)
61
57
  super(definition)
62
-
58
+
59
+ @foreign_keys = []
63
60
  primary_key = target_columns.select(&:primary).first
64
61
  @id_column = IdColumn.new(self, primary_key, target_model, model)
65
-
66
- @excluded_columns = []
62
+
67
63
  @compute = build_compute(definition) || []
68
64
  @methods = build_methods(definition) || []
69
65
  @include = build_children(definition) || {}
70
66
  @base_columns = build_columns(definition) || []
71
67
 
72
- dups = find_dup_columns
73
- if !dups.blank?
74
- raise "#{@excluded_columns.inspect}Duplicate columns found: #{dups.join(", ")}"
75
- end
68
+ validate_columns(all_columns)
69
+
76
70
  self
77
71
  end
72
+
73
+ def validate_columns(columns)
74
+ dups = find_dup_columns(columns)
75
+ if dups.present?
76
+ raise "Duplicate columns found: #{dups.join(", ")}"
77
+ end
78
+ end
78
79
 
79
80
  def children
80
81
  (@base_columns + @compute + @methods + @include.values)
@@ -130,38 +131,54 @@ module FlattenRecord
130
131
  end
131
132
 
132
133
  private
133
- def find_dup_columns
134
+ def find_dup_columns(columns)
134
135
  dups = []
135
- all_columns.each do |column|
136
- all_columns.each do |comp|
137
- if comp.parent != column.parent && comp.name == column.name
138
- parent_target = column.parent.target_model.to_s
139
- original_name = column.column.name
140
- dups << "#{column.name} was from #{parent_target}'s #{original_name}"
141
- end
136
+ columns.each do |column|
137
+ if match_columns?(columns, column)
138
+ parent_target = column.parent.target_model
139
+ original_name = column.column.name
140
+ dups << "#{column.name} was from #{parent_target}'s #{original_name}"
142
141
  end
143
142
  end
144
143
  dups
145
144
  end
146
145
 
147
- def associated_node_factory(parent, child, class_name)
148
- klass_map = [:has_many, :belongs_to, :has_one]
146
+ def match_columns?(columns, column)
147
+ columns.each do |c|
148
+ if c.parent != column.parent && c.name == column.name
149
+ return true
150
+ end
151
+ end
152
+ false
153
+ end
149
154
 
155
+ def associated_node_factory(parent, child, class_name)
150
156
  association = target_model.reflect_on_association(child)
151
- @excluded_columns << association.foreign_key.to_s
152
-
153
- class_name ||= association.klass
154
- node = nil
157
+
158
+ raise_missing_macro(child, target_model) unless association.macro
155
159
 
156
- if klass_map.include?(association.macro)
157
- klass = association.macro.to_s.camelize.to_sym
158
- node = Meta.const_get(klass).new(parent, association, class_name, model)
159
- elsif associaton.macro.nil?
160
- raise "association with '#{child}' on #{target_name} is not found"
160
+ if association_node?(association.macro)
161
+ class_name ||= association.klass
162
+ type = "#{association.macro}"
163
+ klass = Meta.const_get(type.camelize)
164
+
165
+ @foreign_keys << association.foreign_key.to_s
166
+ klass.new(parent, association, class_name, model)
161
167
  else
162
- raise "association type '#{association.macro}' with '#{child}' is not supported"
168
+ raise_unsupported_type(association.macro, target_model)
163
169
  end
164
- node
170
+ end
171
+
172
+ def association_node?(type)
173
+ [:has_many, :belongs_to, :has_one].include?(type)
174
+ end
175
+
176
+ def raise_unsupported_type(type, model)
177
+ raise "association type '#{type}' with '#{model}' is not supported"
178
+ end
179
+
180
+ def raise_missing_macro(child, model)
181
+ raise "association with '#{child}' on #{model} is not found"
165
182
  end
166
183
 
167
184
  def columns_from_definition(definition)
@@ -176,7 +193,7 @@ module FlattenRecord
176
193
 
177
194
  def allow_column?(col, definition)
178
195
  return false if col.primary
179
- return false if @excluded_columns.include?(col.name.to_s)
196
+ return false if @foreign_keys.include?(col.name.to_s)
180
197
 
181
198
  if definition[:only].present?
182
199
  definition[:only].include?(col.name.to_sym)
@@ -1,3 +1,3 @@
1
1
  module FlattenRecord
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
@@ -8,49 +8,51 @@ module FlattenRecord
8
8
  @source_root ||= File.join(File.dirname(__FILE__), 'templates')
9
9
  end
10
10
 
11
- argument :name, :description => 'path to model'
11
+ argument :name, :description => 'model'
12
12
 
13
13
  def generate_files
14
- if !valid?
15
- puts(red("Error. #{name.camelize} is not found")) and return
16
- end
17
-
18
- defined_classes.each do |class_name|
19
- @klass = class_name.constantize
20
- @table_name = @klass.table_name
21
- @table_columns = denormalized_columns if meta
22
-
23
- case
24
- when @klass.table_exists?
25
- puts yellow("Warning. Table already exists: #{@table_name}")
26
- diff_and_generate if meta
27
-
28
- when meta
29
- migration_template('migration.erb', "db/migrate/create_table_#{@table_name}.rb")
30
-
31
- else
32
- puts red("Error. No denormalization definition found in #{@table_name}")
33
- end
14
+ return unless valid?
15
+
16
+ @table_name = klass.table_name
17
+ if klass.table_exists?
18
+ puts "Table already exists: #{@table_name}"
19
+ diff_and_generate
20
+ else
21
+ @table_columns = denormalized_columns
22
+ migration_template('migration.erb', "db/migrate/create_table_#{@table_name}.rb")
34
23
  end
35
24
  end
36
25
 
37
26
  private
38
27
  def meta
39
- @klass.flattener_meta
28
+ klass.flattener_meta
40
29
  end
41
-
30
+
42
31
  def denormalized_columns
43
- @klass.denormalizer_meta.denormalized_columns
32
+ meta.all_columns
44
33
  end
45
-
34
+
35
+ def klass_name
36
+ name.camelize
37
+ end
38
+
39
+ def klass
40
+ klass_name.constantize
41
+ end
42
+
43
+ def table_name
44
+ klass.table_name
45
+ end
46
+
47
+ def flatten_klass_names
48
+ FlattenRecord::Config.included_models
49
+ end
50
+
46
51
  def diff_and_generate
47
52
  if any_diff?
48
- puts blue("Generating migration based on the difference..")
49
- puts ""
50
- puts " #{green('Add columns:')} #{add_columns_names}" unless add_columns.empty?
51
- puts ""
52
- puts " #{red('Drop columns:')} #{drop_columns_names}" unless drop_columns.empty?
53
- puts ""
53
+ puts "Generating migration based on the difference.."
54
+ puts " #{green('Add columns:')} #{add_columns_names}" unless add_columns.empty?
55
+ puts " #{red('Drop columns:')} #{drop_columns_names}" unless drop_columns.empty?
54
56
 
55
57
  @migration = add_columns.empty? ?
56
58
  "drop_#{drop_columns.first.name}_etc_from" :
@@ -60,15 +62,6 @@ module FlattenRecord
60
62
  end
61
63
  end
62
64
 
63
- def colorize(text, color_code)
64
- "\e[#{color_code}m#{text}\e[0m"
65
- end
66
-
67
- def red(text); colorize(text, 31); end
68
- def green(text); colorize(text, 32); end
69
- def yellow(text); colorize(text, 33); end
70
- def blue(text); colorize(text, 34); end
71
-
72
65
  def any_diff?
73
66
  !add_columns.empty? || !drop_columns.empty?
74
67
  end
@@ -81,38 +74,59 @@ module FlattenRecord
81
74
  drop_columns.collect(&:name).join(', ')
82
75
  end
83
76
 
84
- def add_columns
85
- @add_columns ||= denormalized_columns.inject([]) do |cols, col|
86
- cols ||= []
87
- @klass.columns.collect(&:name).include?(col.name) ?
88
- cols : cols << col
89
- end
77
+ def columns
78
+ klass.columns
90
79
  end
91
-
92
- def drop_columns
93
- @drop_columns ||= @klass.columns.inject([]) do |cols, col|
94
- next if col.name == 'id'
95
- cols ||= []
96
- denormalized_columns.collect(&:name).include?(col.name) ?
97
- cols : cols << col
98
- end
80
+
81
+ def denormalized_column_names
82
+ denormalized_columns.map(&:name)
99
83
  end
100
84
 
101
- def denormalized_columns
102
- meta.all_columns
85
+ def column_names
86
+ columns.map(&:name)
103
87
  end
104
88
 
105
- def defined_classes
106
- @klass = name.camelize
107
- [@klass]
89
+ def add_columns
90
+ @add_columns ||=
91
+ denormalized_columns.inject([]) do |cols, col|
92
+ if !column_names.include?(col.name)
93
+ cols << col
94
+ puts "#{col.name}"
95
+ end
96
+ cols
97
+ end
98
+ end
99
+
100
+ def drop_columns
101
+ @drop_columns ||=
102
+ columns.inject([]) do |cols, col|
103
+ if col.name != 'id' && !denormalized_column_names.include?(col.name)
104
+ cols << col
105
+ end
106
+ cols
107
+ end
108
108
  end
109
109
 
110
110
  def valid?
111
111
  Rails.application.eager_load!
112
- @klass = name.camelize
113
- @klasses = FlattenRecord::Config.included_models
114
- @klasses.include?(@klass.to_s)
112
+
113
+ begin
114
+ klass && meta
115
+ rescue Exception => e
116
+ puts red(e.message)
117
+ false
118
+ end
119
+ end
120
+
121
+ def colorize(text, color_code)
122
+ "\e[#{color_code}m#{text}\e[0m"
115
123
  end
124
+
125
+ def red(text); colorize(text, 31); end
126
+ def green(text); colorize(text, 32); end
127
+ def yellow(text); colorize(text, 33); end
128
+ def blue(text); colorize(text, 34); end
129
+
116
130
  end
117
131
  end
118
132
  end