declare_schema 0.8.0.pre.6 → 0.10.1

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/declare_schema_build.yml +1 -1
  3. data/CHANGELOG.md +28 -1
  4. data/Gemfile.lock +1 -1
  5. data/README.md +91 -13
  6. data/lib/declare_schema.rb +46 -0
  7. data/lib/declare_schema/dsl.rb +39 -0
  8. data/lib/declare_schema/extensions/active_record/fields_declaration.rb +23 -4
  9. data/lib/declare_schema/model.rb +51 -59
  10. data/lib/declare_schema/model/field_spec.rb +11 -8
  11. data/lib/declare_schema/model/foreign_key_definition.rb +4 -8
  12. data/lib/declare_schema/model/habtm_model_shim.rb +1 -1
  13. data/lib/declare_schema/model/index_definition.rb +0 -19
  14. data/lib/declare_schema/schema_change/all.rb +22 -0
  15. data/lib/declare_schema/schema_change/base.rb +45 -0
  16. data/lib/declare_schema/schema_change/column_add.rb +27 -0
  17. data/lib/declare_schema/schema_change/column_change.rb +32 -0
  18. data/lib/declare_schema/schema_change/column_remove.rb +20 -0
  19. data/lib/declare_schema/schema_change/column_rename.rb +23 -0
  20. data/lib/declare_schema/schema_change/foreign_key_add.rb +25 -0
  21. data/lib/declare_schema/schema_change/foreign_key_remove.rb +20 -0
  22. data/lib/declare_schema/schema_change/index_add.rb +33 -0
  23. data/lib/declare_schema/schema_change/index_remove.rb +20 -0
  24. data/lib/declare_schema/schema_change/primary_key_change.rb +33 -0
  25. data/lib/declare_schema/schema_change/table_add.rb +37 -0
  26. data/lib/declare_schema/schema_change/table_change.rb +36 -0
  27. data/lib/declare_schema/schema_change/table_remove.rb +22 -0
  28. data/lib/declare_schema/schema_change/table_rename.rb +22 -0
  29. data/lib/declare_schema/version.rb +1 -1
  30. data/lib/generators/declare_schema/migration/migrator.rb +189 -202
  31. data/lib/generators/declare_schema/support/model.rb +4 -4
  32. data/spec/lib/declare_schema/api_spec.rb +7 -7
  33. data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +41 -15
  34. data/spec/lib/declare_schema/field_spec_spec.rb +50 -6
  35. data/spec/lib/declare_schema/generator_spec.rb +3 -3
  36. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +116 -26
  37. data/spec/lib/declare_schema/migration_generator_spec.rb +1891 -845
  38. data/spec/lib/declare_schema/model/column_spec.rb +47 -17
  39. data/spec/lib/declare_schema/model/foreign_key_definition_spec.rb +134 -57
  40. data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +3 -3
  41. data/spec/lib/declare_schema/model/index_definition_spec.rb +188 -77
  42. data/spec/lib/declare_schema/model/table_options_definition_spec.rb +75 -11
  43. data/spec/lib/declare_schema/schema_change/base_spec.rb +75 -0
  44. data/spec/lib/declare_schema/schema_change/column_add_spec.rb +30 -0
  45. data/spec/lib/declare_schema/schema_change/column_change_spec.rb +33 -0
  46. data/spec/lib/declare_schema/schema_change/column_remove_spec.rb +30 -0
  47. data/spec/lib/declare_schema/schema_change/column_rename_spec.rb +28 -0
  48. data/spec/lib/declare_schema/schema_change/foreign_key_add_spec.rb +29 -0
  49. data/spec/lib/declare_schema/schema_change/foreign_key_remove_spec.rb +29 -0
  50. data/spec/lib/declare_schema/schema_change/index_add_spec.rb +56 -0
  51. data/spec/lib/declare_schema/schema_change/index_remove_spec.rb +29 -0
  52. data/spec/lib/declare_schema/schema_change/primary_key_change_spec.rb +69 -0
  53. data/spec/lib/declare_schema/schema_change/table_add_spec.rb +50 -0
  54. data/spec/lib/declare_schema/schema_change/table_change_spec.rb +30 -0
  55. data/spec/lib/declare_schema/schema_change/table_remove_spec.rb +27 -0
  56. data/spec/lib/declare_schema/schema_change/table_rename_spec.rb +27 -0
  57. data/spec/lib/declare_schema_spec.rb +101 -0
  58. data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +71 -13
  59. data/spec/support/acceptance_spec_helpers.rb +2 -2
  60. metadata +33 -3
  61. data/test_responses.txt +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3d3ceea8167afc532a38353f4bdac36fc805762dd2c8f2bf5fdb7895e7fc9886
4
- data.tar.gz: 766a96c62aad5a6360c12a74a2630d52d6ee4c08b44ceeb3dd7309251886ce14
3
+ metadata.gz: 4a529991bad5ab16728f11b3f6c165b62853c3b68713e0ec69d6370d7d3c0e5b
4
+ data.tar.gz: 6a131f8af82b018b843f639e501371cf0db9a65b91a4acb99aea44d3eb1674d9
5
5
  SHA512:
6
- metadata.gz: d9de9bb8b90e978d745b5832ce81553d1156e10810f30304a347dd5e591ccd55fa086982ea32f349634cc1a8ff34fad3798d94ccfcd1fe3351be1f9e5a1f9648
7
- data.tar.gz: 7b569604b9dc7f0ca2b8a8c36ffaede21a85e5f0ca13e39291823cfdf41a7b2f3ee00dedb7dd93e4ddd589a266dee75909f9b33bcb084c1e8929086216dbdee9
6
+ metadata.gz: 655ab291337bf8f11fb249de1b97608e7ff73b14ff543f9248e3f92d9bf1770553b8bc2f962c72e8763d27ae559c35bdff1f12f4b6b460a1d46abfab00e931c0
7
+ data.tar.gz: b67d3340bb42b91bddd0940e0a9e5a895bd57f2017ef8d4712e1e4331ba46e78b17d9f7e9b0e60de9f921232897c0edeffe37621060632ecb18267db1ce15dc0
@@ -57,4 +57,4 @@ jobs:
57
57
  git config --global user.email "dummy@example.com"
58
58
  git config --global user.name "dummy"
59
59
  MYSQL_PORT=3306 bundle exec rake test:prepare_testapp[force]
60
- bundle exec rake test:all < test_responses.txt
60
+ bundle exec rake test:all
data/CHANGELOG.md CHANGED
@@ -4,8 +4,32 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
5
  Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [0.8.0] - UNRELEASED
7
+ ## [0.10.1] - 2021-03-18
8
+ ### Fixed
9
+ - Migration steps are now generated in a defined dependency order, so that--for example--indexes that depend
10
+ on columns are deleted first, before the columns themselves are deleted (since the latter implicitly does the former, which would break the migration when run).
11
+ - Related to the above, down migration steps are now always generated in exactly the reverse order of the up migration steps.
12
+
13
+ ## [0.10.0] - 2021-03-17
14
+ ### Deprecated
15
+ - Deprecated the `fields` DSL method in favor of `declare_schema`.
16
+
17
+ ### Added
18
+ - Added the `declare_schema` method to replace `fields`. We now expect a column's type to come before the name
19
+ i.e. `declare schema { string :title }`. Otherwise, there is no difference between `fields` and `declare_schema`.
20
+
21
+ ## [0.9.0] - 2021-03-01
22
+ ### Added
23
+ - Added configurable default settings for `default_text_limit`, `default_string_limit`, `default_null`,
24
+ `default_generate_foreign_keys` and `default_generate_indexing` to allow developers to adhere to project conventions.
25
+
26
+ ### Changed
27
+ - Moved and deprecated default settings for `default_charset` and `default_collation` from
28
+ `Generators::DeclareSchema::Migration::Migrator` to `::DeclareSchema`
29
+
30
+ ## [0.8.0] - 2021-02-22
8
31
  ### Removed
32
+ - Removed assumption that primary key is named 'id'.
9
33
  - Removed `sql_type` that was confusing because it was actually the same as `type` (ex: :string) and not
10
34
  in fact the SQL type (ex: ``varchar(255)'`).
11
35
 
@@ -130,6 +154,9 @@ using the appropriate Rails configuration attributes.
130
154
  ### Added
131
155
  - Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
132
156
 
157
+ [0.10.1]: https://github.com/Invoca/declare_schema/compare/v0.10.0...v0.10.1
158
+ [0.10.0]: https://github.com/Invoca/declare_schema/compare/v0.9.0...v0.10.0
159
+ [0.9.0]: https://github.com/Invoca/declare_schema/compare/v0.8.0...v0.9.0
133
160
  [0.8.0]: https://github.com/Invoca/declare_schema/compare/v0.7.1...v0.8.0
134
161
  [0.7.1]: https://github.com/Invoca/declare_schema/compare/v0.7.0...v0.7.1
135
162
  [0.7.0]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.7.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- declare_schema (0.8.0.pre.6)
4
+ declare_schema (0.10.1)
5
5
  rails (>= 4.2)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -70,18 +70,85 @@ DeclareSchema::Migration::Migrator.before_generating_migration do
70
70
  end
71
71
  ```
72
72
 
73
- ## Declaring Character Set and Collation
74
- _Note: This feature currently only works for MySQL database configurations._
73
+ ### Global Configuration
74
+ Configurations can be set at the global level to customize default declaration for the following values:
75
75
 
76
- MySQL originally supported UTF-8 in the range of 1-3 bytes (`mb3` or "multi-byte 3")
77
- which covered the full set of Unicode code points at the time: U+0000 - U+FFFF.
78
- But later, Unicode was extended beyond U+FFFF to make room for emojis, and with that
79
- UTF-8 require 1-4 bytes (`mb4` or "multi-byte 4"). With this addition, there has
80
- come a need to dynamically define the character set and collation for individual
81
- tables and columns in the database. With `declare_schema` this can be configured
82
- at three separate levels
76
+ #### Text Limit
77
+ The default text limit can be set using the `DeclareSchema.default_text_limit=` method.
78
+ Note that a `nil` default means that there is no default-- so every declaration must be explicit.
79
+ This will `raise` a `limit: must be provided for field :text...` error when the default value is `nil` and there is no explicit
80
+ declaration.
83
81
 
84
- ### Global Configuration
82
+ For example, adding the following to your `config/initializers` directory will
83
+ set the default `text limit` value to `0xffff`:
84
+
85
+ **declare_schema.rb**
86
+ ```ruby
87
+ # frozen_string_literal: true
88
+
89
+ DeclareSchema.default_text_limit = 0xffff
90
+ ```
91
+
92
+ #### String Limit
93
+ The default string limit can be set using the `DeclareSchema.default_string_limit=` method.
94
+ Note that a `nil` default means that there is no default-- so every declaration must be explicit.
95
+ This will `raise` a `limit: must be provided for field :string...` error when the default value is `nil` and there is no explicit
96
+ declaration.
97
+
98
+ For example, adding the following to your `config/initializers` directory will
99
+ set the default `string limit` value to `255`:
100
+
101
+ **declare_schema.rb**
102
+ ```ruby
103
+ # frozen_string_literal: true
104
+
105
+ DeclareSchema.default_string_limit = 255
106
+ ```
107
+
108
+ #### Null
109
+ The default null value can be set using the `DeclareSchema.default_null=` method.
110
+ Note that a `nil` default means that there is no default-- so every declaration must be explicit.
111
+ This will `raise` a `null: must be provided for field...` error when the default value is `nil` and there is no explicit
112
+ declaration.
113
+
114
+ For example, adding the following to your `config/initializers` directory will
115
+ set the default `null` value to `true`:
116
+
117
+ **declare_schema.rb**
118
+ ```ruby
119
+ # frozen_string_literal: true
120
+
121
+ DeclareSchema.default_null = true
122
+ ```
123
+
124
+ #### Generate Foreign Keys
125
+ The default value for generate foreign keys can be set using the `DeclareSchema.default_generate_foreign_keys=` method.
126
+ This value defaults to `true` and can only be set at the global level.
127
+
128
+ For example, adding the following to your `config/initializers` directory will set
129
+ the default `generate foreign keys` value to `false`:
130
+
131
+ **declare_schema.rb**
132
+ ```ruby
133
+ # frozen_string_literal: true
134
+
135
+ DeclareSchema.default_generate_foreign_keys = false
136
+ ```
137
+
138
+ #### Generate Indexing
139
+ The default value for generate indexing can be set using the `DeclareSchema.default_generate_indexing=` method.
140
+ This value defaults to `true` and can only be set at the global level.
141
+
142
+ For example, adding the following to your `config/initializers` directory will
143
+ set the default `generate indexing` value to `false`:
144
+
145
+ **declare_schema.rb**
146
+ ```ruby
147
+ # frozen_string_literal: true
148
+
149
+ DeclareSchema.default_generate_indexing = false
150
+ ```
151
+ #### Character Set and Collation
85
152
  The character set and collation for all tables and fields can be set at the global level
86
153
  using the `Generators::DeclareSchema::Migrator.default_charset=` and
87
154
  `Generators::DeclareSchema::Migrator.default_collation=` configuration methods.
@@ -93,10 +160,21 @@ turn all tables into `utf8mb4` supporting tables:
93
160
  ```ruby
94
161
  # frozen_string_literal: true
95
162
 
96
- Generators::DeclareSchema::Migration::Migrator.default_charset = "utf8mb4"
97
- Generators::DeclareSchema::Migration::Migrator.default_collation = "utf8mb4_bin"
163
+ DeclareSchema.default_charset = "utf8mb4"
164
+ DeclareSchema.default_collation = "utf8mb4_bin"
98
165
  ```
99
166
 
167
+ ## Declaring Character Set and Collation
168
+ _Note: This feature currently only works for MySQL database configurations._
169
+
170
+ MySQL originally supported UTF-8 in the range of 1-3 bytes (`mb3` or "multi-byte 3")
171
+ which covered the full set of Unicode code points at the time: U+0000 - U+FFFF.
172
+ But later, Unicode was extended beyond U+FFFF to make room for emojis, and with that
173
+ UTF-8 require 1-4 bytes (`mb4` or "multi-byte 4"). With this addition, there has
174
+ come a need to dynamically define the character set and collation for individual
175
+ tables and columns in the database. With `declare_schema` this can be configured
176
+ at three separate levels
177
+
100
178
  ### Table Configuration
101
179
  In order to configure a table's default character set and collation, the `charset` and
102
180
  `collation` arguments can be added to the `fields` block.
@@ -150,5 +228,5 @@ or add it to your `bundler` Gemfile:
150
228
  To run tests:
151
229
  ```
152
230
  rake test:prepare_testapp[force]
153
- rake test:all < test_responses.txt
231
+ rake test:all
154
232
  ```
@@ -21,7 +21,18 @@ module DeclareSchema
21
21
  text: String
22
22
  }.freeze
23
23
 
24
+ @default_charset = "utf8mb4"
25
+ @default_collation = "utf8mb4_bin"
26
+ @default_text_limit = 0xffff_ffff
27
+ @default_string_limit = nil
28
+ @default_null = false
29
+ @default_generate_foreign_keys = true
30
+ @default_generate_indexing = true
31
+
24
32
  class << self
33
+ attr_reader :default_charset, :default_collation, :default_text_limit, :default_string_limit, :default_null,
34
+ :default_generate_foreign_keys, :default_generate_indexing
35
+
25
36
  def to_class(type)
26
37
  case type
27
38
  when Class
@@ -32,6 +43,41 @@ module DeclareSchema
32
43
  raise ArgumentError, "expected Class or Symbol or String: got #{type.inspect}"
33
44
  end
34
45
  end
46
+
47
+ def default_charset=(charset)
48
+ charset.is_a?(String) or raise ArgumentError, "charset must be a string (got #{charset.inspect})"
49
+ @default_charset = charset
50
+ end
51
+
52
+ def default_collation=(collation)
53
+ collation.is_a?(String) or raise ArgumentError, "collation must be a string (got #{collation.inspect})"
54
+ @default_collation = collation
55
+ end
56
+
57
+ def default_text_limit=(text_limit)
58
+ text_limit.nil? or text_limit.is_a?(Integer) or raise ArgumentError, "text limit must be an integer or nil (got #{text_limit.inspect})"
59
+ @default_text_limit = text_limit
60
+ end
61
+
62
+ def default_string_limit=(string_limit)
63
+ string_limit.nil? or string_limit.is_a?(Integer) or raise ArgumentError, "string limit must be an integer or nil (got #{string_limit.inspect})"
64
+ @default_string_limit = string_limit
65
+ end
66
+
67
+ def default_null=(null)
68
+ null.in?([true, false, nil]) or raise ArgumentError, "null must be either true, false, or nil (got #{null.inspect})"
69
+ @default_null = null
70
+ end
71
+
72
+ def default_generate_foreign_keys=(generate_foreign_keys)
73
+ generate_foreign_keys.in?([true, false]) or raise ArgumentError, "generate_foreign_keys must be either true or false (got #{generate_foreign_keys.inspect})"
74
+ @default_generate_foreign_keys = generate_foreign_keys
75
+ end
76
+
77
+ def default_generate_indexing=(generate_indexing)
78
+ generate_indexing.in?([true, false]) or raise ArgumentError, "generate_indexing must be either true or false (got #{generate_indexing.inspect})"
79
+ @default_generate_indexing = generate_indexing
80
+ end
35
81
  end
36
82
  end
37
83
 
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/proxy_object'
4
+
5
+ module DeclareSchema
6
+ class Dsl < BasicObject # avoid Object because that gets extended by lots of gems
7
+ include ::Kernel # but we need the basic class methods
8
+
9
+ instance_methods.each do |m|
10
+ unless m.to_s.starts_with?('__') || m.in?([:object_id, :instance_eval])
11
+ undef_method(m)
12
+ end
13
+ end
14
+
15
+ def initialize(model, options = {})
16
+ @model = model
17
+ @options = options
18
+ end
19
+
20
+ attr_reader :model
21
+
22
+ def timestamps
23
+ field(:created_at, :datetime, null: true)
24
+ field(:updated_at, :datetime, null: true)
25
+ end
26
+
27
+ def optimistic_lock
28
+ field(:lock_version, :integer, default: 1, null: false)
29
+ end
30
+
31
+ def field(name, type, *args, **options)
32
+ @model.declare_field(name, type, *(args + [@options.merge(options)]))
33
+ end
34
+
35
+ def method_missing(type, name, *args)
36
+ field(name, type, *args)
37
+ end
38
+ end
39
+ end
@@ -1,21 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_record'
4
+ require 'declare_schema/dsl'
4
5
  require 'declare_schema/model'
5
6
  require 'declare_schema/field_declaration_dsl'
6
7
 
7
8
  module DeclareSchema
8
- module FieldsDsl
9
+ module Macros
9
10
  def fields(table_options = {}, &block)
10
11
  # Any model that calls 'fields' gets DeclareSchema::Model behavior
11
12
  DeclareSchema::Model.mix_in(self)
12
13
 
13
- # @include_in_migration = false #||= options.fetch(:include_in_migration, true); options.delete(:include_in_migration)
14
14
  @include_in_migration = true
15
15
  @table_options = table_options
16
16
 
17
17
  if block
18
- dsl = DeclareSchema::FieldDeclarationDsl.new(self, null: false)
18
+ dsl = DeclareSchema::FieldDeclarationDsl.new(self)
19
+ if block.arity == 1
20
+ yield dsl
21
+ else
22
+ dsl.instance_eval(&block)
23
+ end
24
+ end
25
+ end
26
+ deprecate :fields, deprecator: ActiveSupport::Deprecation.new('1.0', 'DeclareSchema')
27
+
28
+ def declare_schema(table_options = {}, &block)
29
+ # Any model that calls 'fields' gets DeclareSchema::Model behavior
30
+ DeclareSchema::Model.mix_in(self)
31
+
32
+ # @include_in_migration = false #||= options.fetch(:include_in_migration, true); options.delete(:include_in_migration)
33
+ @include_in_migration = true # TODO: Add back or delete the include_in_migration feature
34
+ @table_options = table_options
35
+
36
+ if block
37
+ dsl = DeclareSchema::Dsl.new(self, null: false)
19
38
  if block.arity == 1
20
39
  yield dsl
21
40
  else
@@ -26,4 +45,4 @@ module DeclareSchema
26
45
  end
27
46
  end
28
47
 
29
- ActiveRecord::Base.singleton_class.prepend DeclareSchema::FieldsDsl
48
+ ActiveRecord::Base.singleton_class.prepend DeclareSchema::Macros
@@ -38,24 +38,24 @@ module DeclareSchema
38
38
 
39
39
  # eval avoids the ruby 1.9.2 "super from singleton method ..." error
40
40
 
41
- eval %(
41
+ eval <<~EOS
42
42
  def self.inherited(klass)
43
43
  unless klass.field_specs.has_key?(inheritance_column)
44
- fields do |f|
44
+ declare_schema do |f|
45
45
  f.field(inheritance_column, :string, limit: 255, null: true)
46
46
  end
47
47
  index(inheritance_column)
48
48
  end
49
49
  super
50
50
  end
51
- )
51
+ EOS
52
52
  end
53
53
  end
54
54
  end
55
55
 
56
56
  module ClassMethods
57
57
  def index(fields, options = {})
58
- # don't double-index fields
58
+ # make index idempotent
59
59
  index_fields_s = Array.wrap(fields).map(&:to_s)
60
60
  unless index_definitions.any? { |index_spec| index_spec.fields == index_fields_s }
61
61
  index_definitions << ::DeclareSchema::Model::IndexDefinition.new(self, fields, options)
@@ -74,7 +74,7 @@ module DeclareSchema
74
74
  end
75
75
 
76
76
  # tell the migration generator to ignore the named index. Useful for existing indexes, or for indexes
77
- # that can't be automatically generated (for example: an prefix index in MySQL)
77
+ # that can't be automatically generated (for example: a prefix index in MySQL)
78
78
  def ignore_index(index_name)
79
79
  ignore_indexes << index_name.to_s
80
80
  end
@@ -85,10 +85,10 @@ module DeclareSchema
85
85
  # declarations.
86
86
  def declare_field(name, type, *args, **options)
87
87
  try(:field_added, name, type, args, options)
88
- add_serialize_for_field(name, type, options)
89
- add_formatting_for_field(name, type)
90
- add_validations_for_field(name, type, args, options)
91
- add_index_for_field(name, args, options)
88
+ _add_serialize_for_field(name, type, options)
89
+ _add_formatting_for_field(name, type)
90
+ _add_validations_for_field(name, type, args, options)
91
+ _add_index_for_field(name, args, options)
92
92
  field_specs[name] = ::DeclareSchema::Model::FieldSpec.new(self, name, type, position: field_specs.size, **options)
93
93
  attr_order << name unless attr_order.include?(name)
94
94
  end
@@ -97,41 +97,10 @@ module DeclareSchema
97
97
  if index_definitions.any?(&:primary_key?)
98
98
  index_definitions
99
99
  else
100
- index_definitions + [rails_default_primary_key]
100
+ index_definitions + [_rails_default_primary_key]
101
101
  end
102
102
  end
103
103
 
104
- if ::Rails::VERSION::MAJOR < 5
105
- def primary_key
106
- super || 'id'
107
- end
108
- end
109
-
110
- # returns the primary key (String) as declared with primary_key =
111
- # unlike the `primary_key` method, DOES NOT query the database to find the actual primary key in use right now
112
- # if no explicit primary key set, returns the default_defined_primary_key
113
- def defined_primary_key
114
- if defined?(@primary_key)
115
- @primary_key&.to_s
116
- end || default_defined_primary_key
117
- end
118
-
119
- # if this is a derived class, returns the base class's defined_primary_key
120
- # otherwise, returns 'id'
121
- def default_defined_primary_key
122
- if self == base_class
123
- 'id'
124
- else
125
- base_class.defined_primary_key
126
- end
127
- end
128
-
129
- private
130
-
131
- def rails_default_primary_key
132
- ::DeclareSchema::Model::IndexDefinition.new(self, [primary_key.to_sym], unique: true, name: DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME)
133
- end
134
-
135
104
  # Extend belongs_to so that it creates a FieldSpec for the foreign key
136
105
  def belongs_to(name, scope = nil, **options)
137
106
  column_options = {}
@@ -172,7 +141,7 @@ module DeclareSchema
172
141
  declare_field(fkey.to_sym, :integer, column_options)
173
142
  if refl.options[:polymorphic]
174
143
  foreign_type = options[:foreign_type] || "#{name}_type"
175
- declare_polymorphic_type_field(foreign_type, column_options)
144
+ _declare_polymorphic_type_field(foreign_type, column_options)
176
145
  index([foreign_type, fkey], index_options) if index_options[:name] != false
177
146
  else
178
147
  index(fkey, index_options) if index_options[:name] != false
@@ -180,26 +149,49 @@ module DeclareSchema
180
149
  end
181
150
  end
182
151
 
152
+ if ::Rails::VERSION::MAJOR < 5
153
+ def primary_key
154
+ super || 'id'
155
+ end
156
+ end
157
+
158
+ # returns the primary key (String) as declared with primary_key =
159
+ # unlike the `primary_key` method, DOES NOT query the database to find the actual primary key in use right now
160
+ # if no explicit primary key set, returns the default_defined_primary_key
161
+ def _defined_primary_key
162
+ if defined?(@primary_key)
163
+ @primary_key&.to_s
164
+ end || _default_defined_primary_key
165
+ end
166
+
167
+ private
168
+
169
+ # if this is a derived class, returns the base class's _defined_primary_key
170
+ # otherwise, returns 'id'
171
+ def _default_defined_primary_key
172
+ if self == base_class
173
+ 'id'
174
+ else
175
+ base_class._defined_primary_key
176
+ end
177
+ end
178
+
179
+ def _rails_default_primary_key
180
+ ::DeclareSchema::Model::IndexDefinition.new(self, [_defined_primary_key.to_sym], unique: true, name: DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME)
181
+ end
182
+
183
183
  # Declares the "foo_type" field that accompanies the "foo_id"
184
184
  # field for a polymorphic belongs_to
185
- def declare_polymorphic_type_field(foreign_type, column_options)
185
+ def _declare_polymorphic_type_field(foreign_type, column_options)
186
186
  declare_field(foreign_type, :string, column_options.merge(limit: 255))
187
187
  # FIXME: Before declare_schema was extracted, this used to now do:
188
188
  # never_show(type_col)
189
189
  # That needs doing somewhere
190
190
  end
191
191
 
192
- # Declare a rich-type for any attribute (i.e. getter method). This
193
- # does not effect the attribute in any way - it just records the
194
- # metadata.
195
- def declare_attr_type(name, type, options = {})
196
- attr_types[name] = klass = DeclareSchema.to_class(type)
197
- klass.try(:declared, self, name, options)
198
- end
199
-
200
192
  # Add field validations according to arguments in the
201
193
  # field declaration
202
- def add_validations_for_field(name, type, args, options)
194
+ def _add_validations_for_field(name, type, args, options)
203
195
  validates_presence_of name if :required.in?(args)
204
196
  validates_uniqueness_of name, allow_nil: !:required.in?(args) if :unique.in?(args)
205
197
 
@@ -218,18 +210,18 @@ module DeclareSchema
218
210
  end
219
211
  end
220
212
 
221
- def add_serialize_for_field(name, type, options)
213
+ def _add_serialize_for_field(name, type, options)
222
214
  if (serialize_class = options.delete(:serialize))
223
215
  type == :string || type == :text or raise ArgumentError, "serialize field type must be :string or :text"
224
216
  serialize_args = Array((serialize_class unless serialize_class == true))
225
217
  serialize(name, *serialize_args)
226
218
  if options.has_key?(:default)
227
- options[:default] = serialized_default(name, serialize_class == true ? Object : serialize_class, options[:default])
219
+ options[:default] = _serialized_default(name, serialize_class == true ? Object : serialize_class, options[:default])
228
220
  end
229
221
  end
230
222
  end
231
223
 
232
- def serialized_default(attr_name, class_name_or_coder, default)
224
+ def _serialized_default(attr_name, class_name_or_coder, default)
233
225
  # copied from https://github.com/rails/rails/blob/7d6cb950e7c0e31c2faaed08c81743439156c9f5/activerecord/lib/active_record/attribute_methods/serialization.rb#L70-L76
234
226
  coder = if class_name_or_coder == ::JSON
235
227
  ActiveRecord::Coders::JSON
@@ -248,7 +240,7 @@ module DeclareSchema
248
240
  end
249
241
  end
250
242
 
251
- def add_formatting_for_field(name, type)
243
+ def _add_formatting_for_field(name, type)
252
244
  if (type_class = DeclareSchema.to_class(type))
253
245
  if "format".in?(type_class.instance_methods)
254
246
  before_validation do |record|
@@ -258,7 +250,7 @@ module DeclareSchema
258
250
  end
259
251
  end
260
252
 
261
- def add_index_for_field(name, args, options)
253
+ def _add_index_for_field(name, args, options)
262
254
  if (to_name = options.delete(:index))
263
255
  index_opts =
264
256
  {
@@ -287,13 +279,13 @@ module DeclareSchema
287
279
  refl
288
280
  end
289
281
  end ||
290
- if (col = column(name.to_s))
282
+ if (col = _column(name.to_s))
291
283
  DeclareSchema::PLAIN_TYPES[col.type] || col.klass
292
284
  end
293
285
  end
294
286
 
295
287
  # Return the entry from #columns for the named column
296
- def column(name)
288
+ def _column(name)
297
289
  defined?(@table_exists) or @table_exists = table_exists?
298
290
  if @table_exists
299
291
  columns_hash[name.to_s]