Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.0.0] - Unreleased
### Changed
- The `timestamps` DSL method to create `created_at` and `updated_at` columns now defaults to `null: false` for `datetime` columns
- The `timestamps` DSL method to allow additional options to be passed to the `datetime` fields

### Fixed
- Fixed a bug where `#validate` methods on core object classes with required arguments was causing model validations to fail

## [2.3.2] - 2025-02-21
### Fixed
- Removed require of `activesupport/proxy_object` which is removed in Rails 8.0
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
declare_schema (2.3.2)
declare_schema (3.0.0.pre.1)
rails (>= 6.0)

GEM
Expand Down
6 changes: 3 additions & 3 deletions lib/declare_schema/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ def initialize(model, **options)

attr_reader :model

def timestamps
field(:created_at, :datetime, null: true)
field(:updated_at, :datetime, null: true)
def timestamps(**options)
field(:created_at, :datetime, null: false, **options)
field(:updated_at, :datetime, null: false, **options)
end
Comment on lines +20 to 23
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a breaking change? Will this cause all created_at and updated_at fields to need migrations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 It could be considered breaking, but there is the ability to have previous functionality by using timestamps null: true to override the new default. I think that's enough to not require the breaking change bump, but not strongly opposed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be considered breaking but there is the ability to have previous functionality by using timestamps null: true to override the new default

This is definitely breaking since it requires code changes, its just good practice to provide an easy way of going back to old behavior 😅. This should also be a minor version at the minimum since this is adding new functionality too.

I don't know if other people are really using this gem besides invoca but if there are, we should definitely make this a breaking change.

Or we can split this into two PRs:

  1. Minor version bump: Add new functionality of passing options to timestamp fields.
  2. Major version bump: Change default value of null: true to null: false

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't think there are other users of our gem, I'm fine with doing this as a minor version bump

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. Dependents graph says only 4 other users, so minor seems good for this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But, I agree we should follow best practice here. I'll cut it as major. fd8668e


def optimistic_lock
Expand Down
2 changes: 1 addition & 1 deletion lib/declare_schema/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ def _add_validations_for_field(name, type, args, options)

# Support for custom validations
if (type_class = DeclareSchema.to_class(type))
if type_class.public_method_defined?("validate")
if type_class.public_method_defined?("validate") && type_class.instance_method("validate").arity.zero?
validate do |record|
v = record.send(name)&.validate
record.errors.add(name, v) if v.is_a?(String)
Expand Down
2 changes: 1 addition & 1 deletion lib/declare_schema/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module DeclareSchema
VERSION = "2.3.2"
VERSION = "3.0.0.pre.1"
end
28 changes: 26 additions & 2 deletions spec/lib/declare_schema/migration_generator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,8 @@ class Advert < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinitionInBlo

expect(Generators::DeclareSchema::Migration::Migrator.run).to(
migrate_up(<<~EOS.strip)
add_column :adverts, :created_at, :datetime, null: true
add_column :adverts, :updated_at, :datetime, null: true
add_column :adverts, :created_at, :datetime, null: false
add_column :adverts, :updated_at, :datetime, null: false
add_column :adverts, :lock_version, :integer#{lock_version_limit}, null: false, default: 1
EOS
.and(migrate_down(<<~EOS.strip))
Expand All @@ -486,6 +486,30 @@ class Advert < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinitionInBlo
Advert.field_specs.delete(:created_at)
Advert.field_specs.delete(:lock_version)

### Timestamps with null: true

# `updated_at` and `created_at` can be declared with the shorthand `timestamps` passed with null: true override

class Advert < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinitionInBlock
declare_schema do
timestamps null: true
end
end

expect(Generators::DeclareSchema::Migration::Migrator.run).to(
migrate_up(<<~EOS.strip)
add_column :adverts, :created_at, :datetime, null: true
add_column :adverts, :updated_at, :datetime, null: true
EOS
.and(migrate_down(<<~EOS.strip))
remove_column :adverts, :updated_at
remove_column :adverts, :created_at
EOS
)

Advert.field_specs.delete(:updated_at)
Advert.field_specs.delete(:created_at)

### Indices

# You can add an index to a field definition
Expand Down