From 03075d4e22387a32b26e713fed71f23e871fd123 Mon Sep 17 00:00:00 2001 From: Reece Dunham Date: Tue, 18 Aug 2026 15:07:06 -0400 Subject: [PATCH 1/2] Add .pick finder --- .gitignore | 1 + README.md | 1 + lib/frozen_record/base.rb | 2 +- lib/frozen_record/scope.rb | 6 +++ spec/scope_spec.rb | 78 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 66d58b3..5804bf3 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ test/version_tmp tmp vendor .byebug_history +.idea diff --git a/README.md b/README.md index 4c76fd7..0a86771 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,7 @@ Country.european.republics.part_of_nato.order(id: :desc) ### Supported calculation methods - count + - pick - pluck - ids - minimum diff --git a/lib/frozen_record/base.rb b/lib/frozen_record/base.rb index 557b616..6bb61e7 100644 --- a/lib/frozen_record/base.rb +++ b/lib/frozen_record/base.rb @@ -103,7 +103,7 @@ def current_scope=(scope) end delegate :each, :find_each, :where, :first, :first!, :last, :last!, - :pluck, :ids, :order, :limit, :offset, :minimum, :maximum, :average, :sum, :count, + :pluck, :pick, :ids, :order, :limit, :offset, :minimum, :maximum, :average, :sum, :count, to: :current_scope def file_path diff --git a/lib/frozen_record/scope.rb b/lib/frozen_record/scope.rb index b2f7f0c..050021c 100644 --- a/lib/frozen_record/scope.rb +++ b/lib/frozen_record/scope.rb @@ -78,6 +78,12 @@ def pluck(*attributes) end end + def pick(*attributes) + raise NotImplementedError, '`.pick` without arguments is not supported yet' if attributes.empty? + + limit(1).pluck(*attributes).first + end + def ids pluck(primary_key) end diff --git a/spec/scope_spec.rb b/spec/scope_spec.rb index fa92e47..1f4071c 100644 --- a/spec/scope_spec.rb +++ b/spec/scope_spec.rb @@ -352,6 +352,84 @@ end + describe '.pick' do + + context 'when called with a single argument' do + + it 'returns the value of the first record' do + name = Country.pick(:name) + expect(name).to be == 'Canada' + end + + end + + context 'when called with multiple arguments' do + + it 'returns an array of the values of the first record' do + attributes = Country.pick(:id, :name) + expect(attributes).to be == [1, 'Canada'] + end + + end + + context 'when called without arguments' do + + it 'raises a NotImplementedError' do + expect { Country.pick }.to raise_error(NotImplementedError) + end + + end + + context 'when called on a scope' do + + it 'returns the attribute of the first matching record' do + name = Country.where(continent: 'Europe').pick(:name) + expect(name).to be == 'France' + end + + it 'honors the ordering' do + name = Country.order(name: :desc).pick(:name) + expect(name).to be == 'France' + end + + it 'honors the offset' do + name = Country.offset(1).pick(:name) + expect(name).to be == 'France' + end + + it 'does not alter the receiver scope' do + scope = Country.where(nato: true) + scope.pick(:name) + expect(scope.length).to be == 2 + end + + end + + context 'when no record matches' do + + it 'returns nil when called with a single argument' do + name = Country.where(name: 'not existing').pick(:name) + expect(name).to be_nil + end + + it 'returns nil when called with multiple arguments' do + attributes = Country.where(name: 'not existing').pick(:id, :name) + expect(attributes).to be_nil + end + + end + + context 'when passed an argument that is not an attribute' do + + it 'returns the result of calling the given method name' do + reverse_name = Country.pick(:reverse_name) + expect(reverse_name).to be == 'adanaC' + end + + end + + end + describe '.ids' do context 'when called with no arguments' do From eec0b817cd7454f57986e7b1774462b83a87732c Mon Sep 17 00:00:00 2001 From: Reece Dunham Date: Wed, 19 Aug 2026 07:47:54 -0400 Subject: [PATCH 2/2] Code review feedback Co-authored-by: Jean Boussier --- lib/frozen_record/scope.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/frozen_record/scope.rb b/lib/frozen_record/scope.rb index 050021c..dd2d15c 100644 --- a/lib/frozen_record/scope.rb +++ b/lib/frozen_record/scope.rb @@ -79,8 +79,6 @@ def pluck(*attributes) end def pick(*attributes) - raise NotImplementedError, '`.pick` without arguments is not supported yet' if attributes.empty? - limit(1).pluck(*attributes).first end