From cb9f02afa13f796b62525c587133e9bf0767d54e Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Mon, 18 May 2026 10:47:48 +0100 Subject: [PATCH 1/6] Allow searching on email key in 3 variants --- lib/testing_record/dsl/builder/filters.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/testing_record/dsl/builder/filters.rb b/lib/testing_record/dsl/builder/filters.rb index ebda919..6ff4a48 100644 --- a/lib/testing_record/dsl/builder/filters.rb +++ b/lib/testing_record/dsl/builder/filters.rb @@ -31,7 +31,12 @@ def find_by(attributes) # # @return [TestingRecord::Model, nil] def with_email(email_address) - find_by({ email_address: })&.first&.tap { |entity| entity.class.current = entity } + email_address_results = + find_by({ email_address: }).first || + find_by({ email: email_address }).first || + find_by({ 'email-address': email_address }).first + + email_address_results&.tap { |entity| entity.class.current = entity } end # Checks to see whether an entity exists with the provided id From 9706c9a77c1bec260ed20466430342889a10b99a Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Mon, 18 May 2026 10:51:56 +0100 Subject: [PATCH 2/6] Add in new tests for variants and add name to make debugging easier --- .../dsl/builder/filters_spec.rb | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/spec/testing_record/dsl/builder/filters_spec.rb b/spec/testing_record/dsl/builder/filters_spec.rb index b239148..b52733f 100644 --- a/spec/testing_record/dsl/builder/filters_spec.rb +++ b/spec/testing_record/dsl/builder/filters_spec.rb @@ -5,6 +5,10 @@ Class.new(TestingRecord::Model) do caching :enabled primary_key :email_address + + def self.name + 'FakeModel' + end end end @@ -36,7 +40,7 @@ end end - context 'when entity exists' do + context 'when entity exists with an `email_address` key' do before do model_klazz.create({ email_address: 'foo@bar.com' }) model_klazz.create({ email_address: 'baz@bar.com' }) @@ -46,6 +50,28 @@ expect(model_klazz.with_email('foo@bar.com')).to be_a TestingRecord::Model end end + + context 'when entity exists with an `email-address` key' do + before do + model_klazz.create({ 'email-address': 'foo@bar.com' }) + model_klazz.create({ 'email-address': 'baz@bar.com' }) + end + + it 'finds the first matching model' do + expect(model_klazz.with_email('foo@bar.com')).to be_a TestingRecord::Model + end + end + + context 'when entity exists with an `email` key' do + before do + model_klazz.create({ email: 'foo@bar.com' }) + model_klazz.create({ email: 'baz@bar.com' }) + end + + it 'finds the first matching model' do + expect(model_klazz.with_email('foo@bar.com')).to be_a TestingRecord::Model + end + end end describe '.find_by' do From fc19405e65ef13fcd861c42341402ad817ad7ac4 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Mon, 18 May 2026 11:15:45 +0100 Subject: [PATCH 3/6] Add in new specs for all 3 variants of email address key --- lib/testing_record.rb | 1 + lib/testing_record/model.rb | 4 ++-- spec/testing_record/dsl/builder/filters_spec.rb | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/testing_record.rb b/lib/testing_record.rb index e25bf9f..caa591f 100644 --- a/lib/testing_record.rb +++ b/lib/testing_record.rb @@ -18,6 +18,7 @@ def configure # Configure a default primary key for all TestingRecord models def default_primary_key=(value) raise InvalidConfigurationError, 'Invalid primary key value, must be a Symbol' unless value.is_a?(Symbol) + raise InvalidConfigurationError, 'Primary key value cannot contain `-` please use `_` instead' if value.to_s.include?('-') @default_primary_key = value TestingRecord::Model.primary_key value diff --git a/lib/testing_record/model.rb b/lib/testing_record/model.rb index 6c96a3e..25fd59b 100644 --- a/lib/testing_record/model.rb +++ b/lib/testing_record/model.rb @@ -25,7 +25,7 @@ class << self # # @return [TestingRecord::Model] def create(attributes) - attributes.transform_keys!(&:to_sym) + attributes.transform_keys! { |key| key.to_s.tr('-', '_').to_sym } if respond_to?(:all) create_with_caching(attributes) else @@ -135,7 +135,7 @@ def to_s # # @return [TestingRecord::Model] def update(attrs) - attrs.transform_keys(&:to_sym).each do |key, value| + attrs.transform_keys! { |key| key.to_s.tr('-', '_').to_sym }.each do |key, value| attributes[key] = value instance_variable_set("@#{key}", value) TestingRecord.logger.info("Updated '#{key}' on the #{self.class} entity to be '#{value}'") diff --git a/spec/testing_record/dsl/builder/filters_spec.rb b/spec/testing_record/dsl/builder/filters_spec.rb index b52733f..9a3624c 100644 --- a/spec/testing_record/dsl/builder/filters_spec.rb +++ b/spec/testing_record/dsl/builder/filters_spec.rb @@ -57,13 +57,14 @@ def self.name model_klazz.create({ 'email-address': 'baz@bar.com' }) end - it 'finds the first matching model' do + it 'finds the first matching model (which is stored as a snake_cased key)' do expect(model_klazz.with_email('foo@bar.com')).to be_a TestingRecord::Model end end context 'when entity exists with an `email` key' do before do + model_klazz.primary_key :email model_klazz.create({ email: 'foo@bar.com' }) model_klazz.create({ email: 'baz@bar.com' }) end From 82ae2ab13ebdfa7fbc7dc521e8e6e344ab4c9c16 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Mon, 18 May 2026 11:23:13 +0100 Subject: [PATCH 4/6] Add tests for the snake_casing of hyphenated keys in the model proper; --- spec/testing_record/model_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/testing_record/model_spec.rb b/spec/testing_record/model_spec.rb index 90737be..7a61449 100644 --- a/spec/testing_record/model_spec.rb +++ b/spec/testing_record/model_spec.rb @@ -85,6 +85,21 @@ expect(primary_model_entity).to respond_to(:attributes, :id, :foo, :bar) end end + + context 'with any hyphenated keys' do + before do + FakeModel.caching :enabled + FakeModel.create({ id: 1, snake_case: :whatever, 'hyphenated-case': :no_op, 'hyphenated-case-two': :no_op }) + end + + it 'stores the hyphenated keys as snake_cased keys in the attributes hash' do + expect(FakeModel.current.attributes).to eq({ hyphenated_case: :no_op, hyphenated_case_two: :no_op, id: 1, snake_case: :whatever }) + end + + it 'stores the hyphenated keys as snake_cased reader methods' do + expect(FakeModel.current).to respond_to(:hyphenated_case, :hyphenated_case_two) + end + end end describe '.current=' do From f58459616e0059f7c4b48898606785351981f200 Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Mon, 18 May 2026 11:24:29 +0100 Subject: [PATCH 5/6] Add note for fixed issue --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d4d74d..363faf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ their own custom filters on top of this method ### Fixed +- Hyphenated keys are not permitted for the `primary_key` setting as this will cause issues with ruby ### Security From 7bd4fccd850e48a117fdbe37a8feff78290f3fbd Mon Sep 17 00:00:00 2001 From: Luke Hill Date: Mon, 18 May 2026 11:26:07 +0100 Subject: [PATCH 6/6] Add in changelog for .with_email --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 363faf6..a1f6b30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ### Changed - Exposed `.find_by` as a public method for more complex querying of models, and to allow people to write their own custom filters on top of this method +- Hyphenated keys when passed into `.create` or `#update` will now be converted to underscores to ensure consistency with +ruby conventions and to prevent issues with helper generation +- `.with_email` filter now supports `email_address`, `email` and `email-address` key names for better flexibility when +filtering on email addresses ### Fixed - Hyphenated keys are not permitted for the `primary_key` setting as this will cause issues with ruby