declare_schema 0.8.0.pre.3 → 0.9.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -1
- data/Gemfile.lock +1 -1
- data/README.md +90 -12
- data/lib/declare_schema.rb +46 -0
- data/lib/declare_schema/extensions/active_record/fields_declaration.rb +1 -1
- data/lib/declare_schema/model.rb +52 -37
- data/lib/declare_schema/model/column.rb +2 -0
- data/lib/declare_schema/model/field_spec.rb +13 -12
- data/lib/declare_schema/model/foreign_key_definition.rb +5 -3
- data/lib/declare_schema/model/habtm_model_shim.rb +75 -0
- data/lib/declare_schema/model/index_definition.rb +5 -1
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/migrator.rb +23 -97
- data/spec/lib/declare_schema/field_spec_spec.rb +73 -22
- data/spec/lib/declare_schema/interactive_primary_key_spec.rb +3 -3
- data/spec/lib/declare_schema/migration_generator_spec.rb +28 -28
- data/spec/lib/declare_schema/model/habtm_model_shim_spec.rb +148 -0
- data/spec/lib/declare_schema/model/index_definition_spec.rb +11 -1
- data/spec/lib/declare_schema_spec.rb +101 -0
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +12 -2
- metadata +8 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 531940d48f1fe38830944576136ff76e2b29dc69a323a2a8e3f60f431731f104
         | 
| 4 | 
            +
              data.tar.gz: 3afe0ce91fa631f4fa07d10ef1039f788589d440e87245c859db9bbe0179972d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 67270e128e00f45b8ed8393b85ffe65ab4bc7ae197296adacf22c37629bdf5e768d6e204987b67e2d63b3ac0cc79aadb0b02c2c4f60e7e4b85e01f4d24ef55e2
         | 
| 7 | 
            +
              data.tar.gz: c9763a6eacd9d1d1deef9e829072e974ea53a5575f0938a8b4202e4210aa704186022a12e8704c08edde24bc73c2da7f95b467b77f3c81e422df54eddaf2352a
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -4,8 +4,18 @@ 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. | 
| 7 | 
            +
            ## [0.9.0] - 2021-03-01
         | 
| 8 | 
            +
            ### Added
         | 
| 9 | 
            +
            - Added configurable default settings for `default_text_limit`, `default_string_limit`, `default_null`,
         | 
| 10 | 
            +
            `default_generate_foreign_keys` and `default_generate_indexing` to allow developers to adhere to project conventions.
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            ### Changed
         | 
| 13 | 
            +
            - Moved and deprecated default settings for `default_charset` and `default_collation` from
         | 
| 14 | 
            +
            `Generators::DeclareSchema::Migration::Migrator` to `::DeclareSchema`
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            ## [0.8.0] - 2021-02-22
         | 
| 8 17 | 
             
            ### Removed
         | 
| 18 | 
            +
            - Removed assumption that primary key is named 'id'.
         | 
| 9 19 | 
             
            - Removed `sql_type` that was confusing because it was actually the same as `type` (ex: :string) and not
         | 
| 10 20 | 
             
              in fact the SQL type (ex: ``varchar(255)'`).
         | 
| 11 21 |  | 
| @@ -130,6 +140,7 @@ using the appropriate Rails configuration attributes. | |
| 130 140 | 
             
            ### Added
         | 
| 131 141 | 
             
            - Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
         | 
| 132 142 |  | 
| 143 | 
            +
            [0.9.0]: https://github.com/Invoca/declare_schema/compare/v0.8.0...v0.9.0
         | 
| 133 144 | 
             
            [0.8.0]: https://github.com/Invoca/declare_schema/compare/v0.7.1...v0.8.0
         | 
| 134 145 | 
             
            [0.7.1]: https://github.com/Invoca/declare_schema/compare/v0.7.0...v0.7.1
         | 
| 135 146 | 
             
            [0.7.0]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.7.0
         | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -70,18 +70,85 @@ DeclareSchema::Migration::Migrator.before_generating_migration do | |
| 70 70 | 
             
            end
         | 
| 71 71 | 
             
            ```
         | 
| 72 72 |  | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 73 | 
            +
            ### Global Configuration
         | 
| 74 | 
            +
            Configurations can be set at the global level to customize default declaration for the following values:
         | 
| 75 75 |  | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 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 | 
            -
             | 
| 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 | 
            -
             | 
| 97 | 
            -
             | 
| 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.
         | 
    
        data/lib/declare_schema.rb
    CHANGED
    
    | @@ -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 |  | 
    
        data/lib/declare_schema/model.rb
    CHANGED
    
    | @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'rails'
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            require 'declare_schema/extensions/module'
         | 
| 4 6 |  | 
| 5 7 | 
             
            module DeclareSchema
         | 
| @@ -36,7 +38,7 @@ module DeclareSchema | |
| 36 38 |  | 
| 37 39 | 
             
                      # eval avoids the ruby 1.9.2 "super from singleton method ..." error
         | 
| 38 40 |  | 
| 39 | 
            -
                      eval  | 
| 41 | 
            +
                      eval <<~EOS
         | 
| 40 42 | 
             
                        def self.inherited(klass)
         | 
| 41 43 | 
             
                          unless klass.field_specs.has_key?(inheritance_column)
         | 
| 42 44 | 
             
                            fields do |f|
         | 
| @@ -46,14 +48,14 @@ module DeclareSchema | |
| 46 48 | 
             
                          end
         | 
| 47 49 | 
             
                          super
         | 
| 48 50 | 
             
                        end
         | 
| 49 | 
            -
                       | 
| 51 | 
            +
                      EOS
         | 
| 50 52 | 
             
                    end
         | 
| 51 53 | 
             
                  end
         | 
| 52 54 | 
             
                end
         | 
| 53 55 |  | 
| 54 56 | 
             
                module ClassMethods
         | 
| 55 57 | 
             
                  def index(fields, options = {})
         | 
| 56 | 
            -
                    #  | 
| 58 | 
            +
                    # make index idempotent
         | 
| 57 59 | 
             
                    index_fields_s = Array.wrap(fields).map(&:to_s)
         | 
| 58 60 | 
             
                    unless index_definitions.any? { |index_spec| index_spec.fields == index_fields_s }
         | 
| 59 61 | 
             
                      index_definitions << ::DeclareSchema::Model::IndexDefinition.new(self, fields, options)
         | 
| @@ -72,7 +74,7 @@ module DeclareSchema | |
| 72 74 | 
             
                  end
         | 
| 73 75 |  | 
| 74 76 | 
             
                  # tell the migration generator to ignore the named index. Useful for existing indexes, or for indexes
         | 
| 75 | 
            -
                  # that can't be automatically generated (for example:  | 
| 77 | 
            +
                  # that can't be automatically generated (for example: a prefix index in MySQL)
         | 
| 76 78 | 
             
                  def ignore_index(index_name)
         | 
| 77 79 | 
             
                    ignore_indexes << index_name.to_s
         | 
| 78 80 | 
             
                  end
         | 
| @@ -83,10 +85,10 @@ module DeclareSchema | |
| 83 85 | 
             
                  # declarations.
         | 
| 84 86 | 
             
                  def declare_field(name, type, *args, **options)
         | 
| 85 87 | 
             
                    try(:field_added, name, type, args, options)
         | 
| 86 | 
            -
                     | 
| 87 | 
            -
                     | 
| 88 | 
            -
                     | 
| 89 | 
            -
                     | 
| 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)
         | 
| 90 92 | 
             
                    field_specs[name] = ::DeclareSchema::Model::FieldSpec.new(self, name, type, position: field_specs.size, **options)
         | 
| 91 93 | 
             
                    attr_order << name unless attr_order.include?(name)
         | 
| 92 94 | 
             
                  end
         | 
| @@ -95,20 +97,10 @@ module DeclareSchema | |
| 95 97 | 
             
                    if index_definitions.any?(&:primary_key?)
         | 
| 96 98 | 
             
                      index_definitions
         | 
| 97 99 | 
             
                    else
         | 
| 98 | 
            -
                      index_definitions + [ | 
| 100 | 
            +
                      index_definitions + [_rails_default_primary_key]
         | 
| 99 101 | 
             
                    end
         | 
| 100 102 | 
             
                  end
         | 
| 101 103 |  | 
| 102 | 
            -
                  def primary_key
         | 
| 103 | 
            -
                    super || 'id'
         | 
| 104 | 
            -
                  end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                  private
         | 
| 107 | 
            -
             | 
| 108 | 
            -
                  def rails_default_primary_key
         | 
| 109 | 
            -
                    ::DeclareSchema::Model::IndexDefinition.new(self, [primary_key.to_sym], unique: true, name: DeclareSchema::Model::IndexDefinition::PRIMARY_KEY_NAME)
         | 
| 110 | 
            -
                  end
         | 
| 111 | 
            -
             | 
| 112 104 | 
             
                  # Extend belongs_to so that it creates a FieldSpec for the foreign key
         | 
| 113 105 | 
             
                  def belongs_to(name, scope = nil, **options)
         | 
| 114 106 | 
             
                    column_options = {}
         | 
| @@ -149,7 +141,7 @@ module DeclareSchema | |
| 149 141 | 
             
                    declare_field(fkey.to_sym, :integer, column_options)
         | 
| 150 142 | 
             
                    if refl.options[:polymorphic]
         | 
| 151 143 | 
             
                      foreign_type = options[:foreign_type] || "#{name}_type"
         | 
| 152 | 
            -
                       | 
| 144 | 
            +
                      _declare_polymorphic_type_field(foreign_type, column_options)
         | 
| 153 145 | 
             
                      index([foreign_type, fkey], index_options) if index_options[:name] != false
         | 
| 154 146 | 
             
                    else
         | 
| 155 147 | 
             
                      index(fkey, index_options) if index_options[:name] != false
         | 
| @@ -157,26 +149,49 @@ module DeclareSchema | |
| 157 149 | 
             
                    end
         | 
| 158 150 | 
             
                  end
         | 
| 159 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 | 
            +
             | 
| 160 183 | 
             
                  # Declares the "foo_type" field that accompanies the "foo_id"
         | 
| 161 184 | 
             
                  # field for a polymorphic belongs_to
         | 
| 162 | 
            -
                  def  | 
| 185 | 
            +
                  def _declare_polymorphic_type_field(foreign_type, column_options)
         | 
| 163 186 | 
             
                    declare_field(foreign_type, :string, column_options.merge(limit: 255))
         | 
| 164 187 | 
             
                    # FIXME: Before declare_schema was extracted, this used to now do:
         | 
| 165 188 | 
             
                    # never_show(type_col)
         | 
| 166 189 | 
             
                    # That needs doing somewhere
         | 
| 167 190 | 
             
                  end
         | 
| 168 191 |  | 
| 169 | 
            -
                  # Declare a rich-type for any attribute (i.e. getter method). This
         | 
| 170 | 
            -
                  # does not effect the attribute in any way - it just records the
         | 
| 171 | 
            -
                  # metadata.
         | 
| 172 | 
            -
                  def declare_attr_type(name, type, options = {})
         | 
| 173 | 
            -
                    attr_types[name] = klass = DeclareSchema.to_class(type)
         | 
| 174 | 
            -
                    klass.try(:declared, self, name, options)
         | 
| 175 | 
            -
                  end
         | 
| 176 | 
            -
             | 
| 177 192 | 
             
                  # Add field validations according to arguments in the
         | 
| 178 193 | 
             
                  # field declaration
         | 
| 179 | 
            -
                  def  | 
| 194 | 
            +
                  def _add_validations_for_field(name, type, args, options)
         | 
| 180 195 | 
             
                    validates_presence_of   name if :required.in?(args)
         | 
| 181 196 | 
             
                    validates_uniqueness_of name, allow_nil: !:required.in?(args) if :unique.in?(args)
         | 
| 182 197 |  | 
| @@ -195,18 +210,18 @@ module DeclareSchema | |
| 195 210 | 
             
                    end
         | 
| 196 211 | 
             
                  end
         | 
| 197 212 |  | 
| 198 | 
            -
                  def  | 
| 213 | 
            +
                  def _add_serialize_for_field(name, type, options)
         | 
| 199 214 | 
             
                    if (serialize_class = options.delete(:serialize))
         | 
| 200 215 | 
             
                      type == :string || type == :text or raise ArgumentError, "serialize field type must be :string or :text"
         | 
| 201 216 | 
             
                      serialize_args = Array((serialize_class unless serialize_class == true))
         | 
| 202 217 | 
             
                      serialize(name, *serialize_args)
         | 
| 203 218 | 
             
                      if options.has_key?(:default)
         | 
| 204 | 
            -
                        options[:default] =  | 
| 219 | 
            +
                        options[:default] = _serialized_default(name, serialize_class == true ? Object : serialize_class, options[:default])
         | 
| 205 220 | 
             
                      end
         | 
| 206 221 | 
             
                    end
         | 
| 207 222 | 
             
                  end
         | 
| 208 223 |  | 
| 209 | 
            -
                  def  | 
| 224 | 
            +
                  def _serialized_default(attr_name, class_name_or_coder, default)
         | 
| 210 225 | 
             
                    # copied from https://github.com/rails/rails/blob/7d6cb950e7c0e31c2faaed08c81743439156c9f5/activerecord/lib/active_record/attribute_methods/serialization.rb#L70-L76
         | 
| 211 226 | 
             
                    coder = if class_name_or_coder == ::JSON
         | 
| 212 227 | 
             
                              ActiveRecord::Coders::JSON
         | 
| @@ -225,7 +240,7 @@ module DeclareSchema | |
| 225 240 | 
             
                    end
         | 
| 226 241 | 
             
                  end
         | 
| 227 242 |  | 
| 228 | 
            -
                  def  | 
| 243 | 
            +
                  def _add_formatting_for_field(name, type)
         | 
| 229 244 | 
             
                    if (type_class = DeclareSchema.to_class(type))
         | 
| 230 245 | 
             
                      if "format".in?(type_class.instance_methods)
         | 
| 231 246 | 
             
                        before_validation do |record|
         | 
| @@ -235,7 +250,7 @@ module DeclareSchema | |
| 235 250 | 
             
                    end
         | 
| 236 251 | 
             
                  end
         | 
| 237 252 |  | 
| 238 | 
            -
                  def  | 
| 253 | 
            +
                  def _add_index_for_field(name, args, options)
         | 
| 239 254 | 
             
                    if (to_name = options.delete(:index))
         | 
| 240 255 | 
             
                      index_opts =
         | 
| 241 256 | 
             
                        {
         | 
| @@ -264,13 +279,13 @@ module DeclareSchema | |
| 264 279 | 
             
                          refl
         | 
| 265 280 | 
             
                        end
         | 
| 266 281 | 
             
                      end ||
         | 
| 267 | 
            -
                      if (col =  | 
| 282 | 
            +
                      if (col = _column(name.to_s))
         | 
| 268 283 | 
             
                        DeclareSchema::PLAIN_TYPES[col.type] || col.klass
         | 
| 269 284 | 
             
                      end
         | 
| 270 285 | 
             
                  end
         | 
| 271 286 |  | 
| 272 287 | 
             
                  # Return the entry from #columns for the named column
         | 
| 273 | 
            -
                  def  | 
| 288 | 
            +
                  def _column(name)
         | 
| 274 289 | 
             
                    defined?(@table_exists) or @table_exists = table_exists?
         | 
| 275 290 | 
             
                    if @table_exists
         | 
| 276 291 | 
             
                      columns_hash[name.to_s]
         | 
| @@ -44,6 +44,8 @@ module DeclareSchema | |
| 44 44 | 
             
                        if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
         | 
| 45 45 | 
             
                          types[:text][:limit]    ||= 0xffff
         | 
| 46 46 | 
             
                          types[:binary][:limit]  ||= 0xffff
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                          types[:varbinary] ||= { name: "varbinary" } # TODO: :varbinary is an Invoca addition to Rails; make it a configurable option
         | 
| 47 49 | 
             
                        end
         | 
| 48 50 | 
             
                      end
         | 
| 49 51 | 
             
                    end
         |