Skip to content

Commit

Permalink
Use parameters to amoeba_dup in set
Browse files Browse the repository at this point in the history
  • Loading branch information
jrmhaig committed Jun 30, 2024
1 parent 65b72d0 commit ff08351
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 13 deletions.
16 changes: 16 additions & 0 deletions docs/pre_processing_fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,22 @@ current time:
end
```

Keyword parameters passed to the `amoeba_dup` command can also be used:

```ruby
amoeba do
set string_field: ->(str_arg:) { str_arg }
set integer_field: ->(int_arg:) { int_arg }
set combined_field: ->(str_arg:, int_arg: 33, other_arg: 'default') { "#{str_arg} - #{int_arg} - #{other_arg}" }
end

new_item = item.amoeba_dup(str_arg: 'new string', int_arg: 45)
# => new_item.string_field = 'new_string'
# => new_item.integer_field = 99
# => new_item.combined_field = 'new_string - 99 - default'
```


## regex

To do
Expand Down
11 changes: 8 additions & 3 deletions lib/amoeba/cloner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ class Cloner

def_delegators :object_klass, :amoeba, :fresh_amoeba, :reset_amoeba

def initialize(object, options = {})
def initialize(object, **kwargs)
@old_object = object
@options = options
@params = kwargs
@object_klass = @old_object.class
inherit_parent_settings
@new_object = object.__send__(amoeba.dup_method)
Expand Down Expand Up @@ -135,7 +135,12 @@ def process_null_fields
def process_coercions
# prepend any extra strings to indicate uniqueness of the new record(s)
amoeba.coercions.each do |field, coercion|
@new_object[field] = coercion.is_a?(Proc) ? coercion.call : coercion.to_s
if coercion.is_a?(Proc)
keys = coercion.parameters.select { |pair| %i[key keyreq].include?(pair.first) }.map(&:second)
@new_object[field] = coercion.call(**@params.slice(*keys))
else
@new_object[field] = coercion.to_s
end
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/amoeba/instance_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ def _parent_amoeba_settings
end
end

def amoeba_dup(options = {})
::Amoeba::Cloner.new(self, options).run
def amoeba_dup(**kwargs)
::Amoeba::Cloner.new(self, **kwargs).run
end
end
end
2 changes: 1 addition & 1 deletion lib/amoeba/macros/has_many.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def follow_without_clone(relation_name, association)
return if association.is_a?(ActiveRecord::Reflection::ThroughReflection)

@old_object.__send__(relation_name).each do |old_obj|
copy_of_obj = old_obj.amoeba_dup(@options)
copy_of_obj = old_obj.amoeba_dup
copy_of_obj[:"#{association.foreign_key}"] = nil
relation_name = remapped_relation_name(relation_name)
# associate this new child to the new parent object
Expand Down
2 changes: 1 addition & 1 deletion lib/amoeba/macros/has_one.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def follow(relation_name, association)
old_obj = @old_object.__send__(relation_name)
return unless old_obj

copy_of_obj = old_obj.amoeba_dup(@options)
copy_of_obj = old_obj.amoeba_dup
copy_of_obj[:"#{association.foreign_key}"] = nil
relation_name = remapped_relation_name(relation_name)
@new_object.__send__(:"#{relation_name}=", copy_of_obj)
Expand Down
52 changes: 46 additions & 6 deletions spec/lib/amoeba/class_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

RSpec.describe Amoeba::ClassMethods do
describe '#amoeba' do
let(:dup) { test.amoeba_dup }
let(:test) { TestModel.new(**params) }
let(:dup) { original.amoeba_dup(**dup_params) }
# let(:test) { TestModel.new(**params) }
let(:dup_params) { {} }

before do
stub_const 'TestModel', Class.new(ActiveRecord::Base)
Expand All @@ -22,7 +23,7 @@

describe 'set' do
context 'with a static string value' do
let(:params) { { test_field: 'original string' } }
let(:original) { TestModel.new(test_field: 'original string') }
let(:field_type) { :string }
let(:config) do
<<~CONFIG
Expand All @@ -36,7 +37,7 @@
end

context 'with a static integer value' do
let(:params) { { test_field: 33 } }
let(:original) { TestModel.new(test_field: 33) }
let(:field_type) { :integer }
let(:config) do
<<~CONFIG
Expand All @@ -50,7 +51,7 @@
end

context 'with a static boolean value' do
let(:params) { { test_field: true } }
let(:original) { TestModel.new(test_field: true) }
let(:field_type) { :boolean }
let(:config) do
<<~CONFIG
Expand All @@ -64,7 +65,7 @@
end

context 'with a datetime field set by a lambda' do
let(:params) { { test_field: DateTime.parse('30 Jun 2024 18:19') } }
let(:original) { TestModel.new(test_field: DateTime.parse('30 Jun 2024 18:19')) }
let(:field_type) { :datetime }
let(:config) do
<<~CONFIG
Expand All @@ -79,6 +80,45 @@

it { expect(dup.test_field).to eq(DateTime.parse('1 Jul 2024 09:35')) }
end

context 'with a field set by a parameter' do
let(:original) { TestModel.new(test_field: 'original string') }
let(:dup_params) { { str_arg: 'new string arg' } }
let(:field_type) { :string }
let(:config) do
<<~CONFIG
amoeba do
set test_field: ->(str_arg:) { ">> \#{str_arg} <<" }
end
CONFIG
end

it { expect(dup.test_field).to eq('>> new string arg <<') }
end

context 'with fields set by different parameters' do
let(:original) { TestModel.new(test_field: 'original string', second_test_field: 33, third_test_field: '') }
let(:dup_params) { { str_arg: 'new string arg', int_arg: 99 } }
let(:field_type) { :string }
let(:config) do
<<~CONFIG
amoeba do
set test_field: ->(str_arg:) { ">> \#{str_arg} <<" }
set second_test_field: ->(int_arg:) { int_arg * 2 }
set third_test_field: ->(str_arg:, int_arg: 33, other_arg: 'default') { "\#{str_arg} - \#{int_arg} - default" }
end
CONFIG
end

before do
ActiveRecord::Base.connection.add_column :test_models, :second_test_field, :integer
ActiveRecord::Base.connection.add_column :test_models, :third_test_field, :string
end

it { expect(dup.test_field).to eq('>> new string arg <<') }
it { expect(dup.second_test_field).to eq(198) }
it { expect(dup.third_test_field).to eq('new string arg - 99 - default') }
end
end
end
end

0 comments on commit ff08351

Please sign in to comment.