duty_free 1.0.0 → 1.0.5

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.
@@ -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
  - - ">="