duty_free 1.0.0 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -40,26 +40,25 @@ module DutyFree
40
40
  assocs = {}
41
41
  this_klass.reflect_on_all_associations.each do |assoc|
42
42
  # PolymorphicReflection AggregateReflection RuntimeReflection
43
- is_belongs_to = assoc.is_a?(ActiveRecord::Reflection::BelongsToReflection)
43
+ is_belongs_to = assoc.belongs_to? # is_a?(ActiveRecord::Reflection::BelongsToReflection)
44
44
  # Figure out if it's belongs_to, has_many, or has_one
45
+ # HasAndBelongsToManyReflection
45
46
  belongs_to_or_has_many =
46
47
  if is_belongs_to
47
48
  'belongs_to'
48
- elsif (is_habtm = assoc.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection))
49
+ elsif (is_habtm = assoc.respond_to?(:macro) ? (assoc.macro == :has_and_belongs_to_many) : assoc.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection))
49
50
  'has_and_belongs_to_many'
51
+ elsif assoc.respond_to?(:macro) ? (assoc.macro == :has_many) : assoc.is_a?(ActiveRecord::Reflection::HasManyReflection)
52
+ 'has_many'
50
53
  else
51
- (assoc.is_a?(ActiveRecord::Reflection::HasManyReflection) ? 'has_many' : 'has_one')
54
+ 'has_one'
52
55
  end
53
56
  # Always process belongs_to, and also process has_one and has_many if do_has_many is chosen.
54
57
  # Skip any HMT or HABTM. (Maybe break out HABTM into a combo HM and BT in the future.)
55
58
  if is_habtm
56
- unless ActiveRecord::Base.connection.table_exists?(assoc.join_table)
57
- puts "* In the #{this_klass.name} model there's a problem with: \"has_and_belongs_to_many :#{assoc.name}\" because join table \"#{assoc.join_table}\" does not exist. You can create it with a create_join_table migration."
58
- end
59
+ puts "* In the #{this_klass.name} model there's a problem with: \"has_and_belongs_to_many :#{assoc.name}\" because join table \"#{assoc.join_table}\" does not exist. You can create it with a create_join_table migration." unless ActiveRecord::Base.connection.table_exists?(assoc.join_table)
59
60
  # %%% Search for other associative candidates to use instead of this HABTM contraption
60
- if assoc.options.include?(:through)
61
- puts "* In the #{this_klass.name} model there's a problem with: \"has_and_belongs_to_many :#{assoc.name}\" because it includes \"through: #{assoc.options[:through].inspect}\" which is pointless and should be removed."
62
- end
61
+ puts "* In the #{this_klass.name} model there's a problem with: \"has_and_belongs_to_many :#{assoc.name}\" because it includes \"through: #{assoc.options[:through].inspect}\" which is pointless and should be removed." if assoc.options.include?(:through)
63
62
  end
64
63
  if (is_through = assoc.is_a?(ActiveRecord::Reflection::ThroughReflection)) && assoc.options.include?(:as)
65
64
  puts "* In the #{this_klass.name} model there's a problem with: \"has_many :#{assoc.name} through: #{assoc.options[:through].inspect}\" because it also includes \"as: #{assoc.options[:as].inspect}\", so please choose either for this line to be a \"has_many :#{assoc.name} through:\" or to be a polymorphic \"has_many :#{assoc.name} as:\". It can't be both."
@@ -167,7 +166,7 @@ module DutyFree
167
166
  # belongs_to is more involved since there may be multiple foreign keys which point
168
167
  # from the foreign table to this primary one, so exclude all these links.
169
168
  _find_belongs_tos(assoc.first.last, assoc.last, errored_assocs).map do |f_assoc|
170
- [f_assoc.foreign_key.to_s, f_assoc.active_record]
169
+ [[f_assoc.foreign_key.to_s], f_assoc.active_record]
171
170
  end
172
171
  end
173
172
  # puts "New Poison: #{new_poison_links.inspect}"
@@ -182,7 +181,8 @@ module DutyFree
182
181
  # Find belongs_tos for this model to one more more other klasses
183
182
  def self._find_belongs_tos(klass, to_klass, errored_assocs)
184
183
  klass.reflect_on_all_associations.each_with_object([]) do |bt_assoc, s|
185
- next unless bt_assoc.is_a?(ActiveRecord::Reflection::BelongsToReflection) && !errored_assocs.include?(bt_assoc)
184
+ # .is_a?(ActiveRecord::Reflection::BelongsToReflection)
185
+ next unless bt_assoc.belongs_to? && !errored_assocs.include?(bt_assoc)
186
186
 
187
187
  begin
188
188
  s << bt_assoc if !bt_assoc.polymorphic? && bt_assoc.klass == to_klass
@@ -203,9 +203,7 @@ module DutyFree
203
203
 
204
204
  # Requireds takes its cues from all attributes having a presence validator
205
205
  requireds = _find_requireds(klass)
206
- if priority_excluded_columns
207
- klass_columns = klass_columns.reject { |col| priority_excluded_columns.include?(col.name) }
208
- end
206
+ klass_columns = klass_columns.reject { |col| priority_excluded_columns.include?(col.name) } if priority_excluded_columns
209
207
  excluded_columns = %w[created_at updated_at deleted_at]
210
208
  unique = [(
211
209
  # Find the first text field of a required if one exists
@@ -240,18 +238,24 @@ module DutyFree
240
238
  if klass.columns.map(&:name).include?(attrib)
241
239
  s << attrib
242
240
  else
243
- puts "* In the #{klass.name} model \"validates_presence_of :#{attrib}\" should be removed as it does not refer to any existing column."
244
- errored_columns << klass_col
241
+ bt_names = klass.reflect_on_all_associations.each_with_object([]) do |assoc, names|
242
+ names << assoc.name.to_s if assoc.is_a?(ActiveRecord::Reflection::BelongsToReflection)
243
+ names
244
+ end
245
+ unless bt_names.include?(attrib)
246
+ puts "* In the #{klass.name} model \"validates_presence_of :#{attrib}\" should be removed as it does not refer to any existing column."
247
+ errored_columns << klass_col
248
+ end
245
249
  end
246
250
  end
247
251
  end
248
252
  end
249
253
 
250
- # Show a "pretty" version of IMPORT_COLUMNS, to be placed in a model
254
+ # Show a "pretty" version of IMPORT_TEMPLATE, to be placed in a model
251
255
  def self._template_pretty_print(template, indent = 0, child_count = 0, is_hash_in_hash = false)
252
256
  unless indent.negative?
253
257
  if indent.zero?
254
- print 'IMPORT_COLUMNS = '
258
+ print 'IMPORT_TEMPLATE = '
255
259
  else
256
260
  puts unless is_hash_in_hash
257
261
  end
@@ -305,7 +309,7 @@ module DutyFree
305
309
  if indent == 2
306
310
  puts
307
311
  indent = 0
308
- puts '}'
312
+ puts '}.freeze'
309
313
  elsif indent >= 0
310
314
  print "#{' ' unless child_count.zero?}}"
311
315
  end
@@ -35,20 +35,34 @@ module DutyFree
35
35
  end
36
36
 
37
37
  # ActiveRecord AREL objects
38
- elsif piece.is_a?(Arel::Nodes::JoinSource)
39
- # The left side is the "FROM" table
40
- # names += _recurse_arel(piece.left)
41
- # The right side is an array of all JOINs
42
- names += piece.right.inject([]) { |s, v| s + _recurse_arel(v) }
43
38
  elsif piece.is_a?(Arel::Nodes::Join) # INNER or OUTER JOIN
44
- # The left side is the "JOIN" table
45
- names += _recurse_arel(piece.left)
46
- # (The right side of these is the "ON" clause)
39
+ # rubocop:disable Style/IdenticalConditionalBranches
40
+ if piece.right.is_a?(Arel::Table) # Came in from AR < 3.2?
41
+ # Arel 2.x and older is a little curious because these JOINs work "back to front".
42
+ # The left side here is either another earlier JOIN, or at the end of the whole tree, it is
43
+ # the first table.
44
+ names += _recurse_arel(piece.left)
45
+ # The right side here at the top is the very last table, and anywhere else down the tree it is
46
+ # the later "JOIN" table of this pair. (The table that comes after all the rest of the JOINs
47
+ # from the left side.)
48
+ names << piece.right.name
49
+ else # "Normal" setup, fed from a JoinSource which has an array of JOINs
50
+ # The left side is the "JOIN" table
51
+ names += _recurse_arel(piece.left)
52
+ # (The right side of these is the "ON" clause)
53
+ end
54
+ # rubocop:enable Style/IdenticalConditionalBranches
47
55
  elsif piece.is_a?(Arel::Table) # Table
48
56
  names << piece.name
49
57
  elsif piece.is_a?(Arel::Nodes::TableAlias) # Alias
50
58
  # Can get the real table name from: self._recurse_arel(piece.left)
51
59
  names << piece.right.to_s # This is simply a string; the alias name itself
60
+ elsif piece.is_a?(Arel::Nodes::JoinSource) # Leaving this until the end because AR < 3.2 doesn't know at all about JoinSource!
61
+ # The left side is the "FROM" table
62
+ # names += _recurse_arel(piece.left)
63
+ names << piece.left.name
64
+ # The right side is an array of all JOINs
65
+ names += piece.right.inject([]) { |s, v| s + _recurse_arel(v) }
52
66
  end
53
67
  names
54
68
  end
@@ -57,11 +71,11 @@ module DutyFree
57
71
  prefixes.reject(&:blank?).join(separator || '.')
58
72
  end
59
73
 
60
- def self._clean_name(name, import_columns_as)
74
+ def self._clean_name(name, import_template_as)
61
75
  return name if name.is_a?(Symbol)
62
76
 
63
77
  # Expand aliases
64
- (import_columns_as || []).each do |k, v|
78
+ (import_template_as || []).each do |k, v|
65
79
  if (k[-1] == ' ' && name.start_with?(k)) || name == k
66
80
  name.replace(v + name[k.length..-1])
67
81
  break
@@ -5,7 +5,7 @@ module DutyFree
5
5
  module VERSION
6
6
  MAJOR = 1
7
7
  MINOR = 0
8
- TINY = 0
8
+ TINY = 5
9
9
 
10
10
  # PRE is nil unless it's a pre-release (beta, RC, etc.)
11
11
  PRE = nil
@@ -1,2 +1,2 @@
1
1
  Description:
2
- Generates (but does not run) a migration to add a versions table.
2
+ Modifies an existing model so that it includes an IMPORT_TEMPLATE.
@@ -4,18 +4,10 @@ require 'rails/generators'
4
4
  require 'rails/generators/active_record'
5
5
 
6
6
  module DutyFree
7
- # Installs DutyFree in a rails app.
7
+ # Auto-generates an IMPORT_TEMPLATE entry for one or more models
8
8
  class InstallGenerator < ::Rails::Generators::Base
9
9
  include ::Rails::Generators::Migration
10
10
 
11
- # Class names of MySQL adapters.
12
- # - `MysqlAdapter` - Used by gems: `mysql`, `activerecord-jdbcmysql-adapter`.
13
- # - `Mysql2Adapter` - Used by `mysql2` gem.
14
- MYSQL_ADAPTERS = [
15
- 'ActiveRecord::ConnectionAdapters::MysqlAdapter',
16
- 'ActiveRecord::ConnectionAdapters::Mysql2Adapter'
17
- ].freeze
18
-
19
11
  source_root File.expand_path('templates', __dir__)
20
12
  class_option(
21
13
  :with_changes,
@@ -68,8 +60,14 @@ module DutyFree
68
60
  "[#{major}.#{ActiveRecord::VERSION::MINOR}]"
69
61
  end
70
62
 
63
+ # Class names of MySQL adapters.
64
+ # - `MysqlAdapter` - Used by gems: `mysql`, `activerecord-jdbcmysql-adapter`.
65
+ # - `Mysql2Adapter` - Used by `mysql2` gem.
71
66
  def mysql?
72
- MYSQL_ADAPTERS.include?(ActiveRecord::Base.connection.class.name)
67
+ [
68
+ 'ActiveRecord::ConnectionAdapters::MysqlAdapter',
69
+ 'ActiveRecord::ConnectionAdapters::Mysql2Adapter'
70
+ ].freeze.include?(ActiveRecord::Base.connection.class.name)
73
71
  end
74
72
 
75
73
  # Even modern versions of MySQL still use `latin1` as the default character
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duty_free
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorin Thwaits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-29 00:00:00.000000000 Z
11
+ date: 2020-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,20 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '3.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '6.0'
22
+ version: '6.1'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '4.2'
29
+ version: '3.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '6.0'
32
+ version: '6.1'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: appraisal
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -45,19 +45,19 @@ dependencies:
45
45
  - !ruby/object:Gem::Version
46
46
  version: '2.2'
47
47
  - !ruby/object:Gem::Dependency
48
- name: byebug
48
+ name: pry-byebug
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ">="
51
+ - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0'
53
+ version: 3.7.0
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ">="
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '0'
60
+ version: 3.7.0
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: ffaker
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -204,10 +204,9 @@ dependencies:
204
204
  - - "~>"
205
205
  - !ruby/object:Gem::Version
206
206
  version: '1.4'
207
- description: |
208
- An ActiveRecord extension that simplifies importing and exporting of data
209
- stored in one or more models. Source and destination can be CSV, XLS,
210
- XLSX, ODT, HTML tables, or simple Ruby arrays.
207
+ description: 'Simplify data imports and exports with this slick ActiveRecord extension
208
+
209
+ '
211
210
  email: lorint@gmail.com
212
211
  executables: []
213
212
  extensions: []
@@ -243,7 +242,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
243
242
  requirements:
244
243
  - - ">="
245
244
  - !ruby/object:Gem::Version
246
- version: 2.4.0
245
+ version: 2.3.5
247
246
  required_rubygems_version: !ruby/object:Gem::Requirement
248
247
  requirements:
249
248
  - - ">="