Skip to content

Commit

Permalink
add destroy objects during save (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
grosendo2006 authored Jul 8, 2024
1 parent 4c9ea35 commit 315356a
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 2 deletions.
4 changes: 3 additions & 1 deletion .reek.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ detectors:
allow_calls: []
FeatureEnvy:
enabled: true
exclude: ['YAAF::Form#promote_legacy_errors']
exclude:
- 'YAAF::Form#promote_legacy_errors'
- 'YAAF::Form#save_models'
InstanceVariableAssumption:
enabled: false
IrresponsibleModule:
Expand Down
4 changes: 3 additions & 1 deletion lib/yaaf/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ def save_in_transaction(options)
def save_models(options)
options.merge!(validate: false)

models.map { |model| model.save!(**options) }
models.map do |model|
model.marked_for_destruction? ? model.destroy! : model.save!(**options)
end
end

def validate_models
Expand Down
1 change: 1 addition & 0 deletions spec/support/forms.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
require_relative 'forms/with_validation_callbacks_form'
require_relative 'forms/with_callback_exception_raising'
require_relative 'forms/custom_transaction_form'
require_relative 'forms/user_destroy_form'
21 changes: 21 additions & 0 deletions spec/support/forms/user_destroy_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class UserDestroyForm < YAAF::Form
attr_accessor :email, :name

before_save :mark_user_for_destruction

def initialize(args)
super(args)

@models = [user]
end

def user
@user ||= User.find_or_initialize_by(email: email)
end

private

def mark_user_for_destruction
user.mark_for_destruction
end
end
101 changes: 101 additions & 0 deletions spec/yaaf/user_destroy_form_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# frozen_string_literal: true

RSpec.describe 'UserDestroyForm form' do
let(:user_destroy_form) { UserDestroyForm.new(args) }
let(:args) do
{ email: '[email protected]', name: 'John' }
end
let(:user_args) { args }
let!(:user) { User.create(user_args) }

describe '#save' do
subject { user_destroy_form.save }

context 'when the user exists' do
before do
expect(user_destroy_form).to be_valid
end

it 'returns true' do
expect(subject).to eq true
end

it 'deletes the user' do
expect { subject }.to change { User.count }.by(-1)
end
end

context 'when the user doesn\'t exist' do
let(:user_args) do
{ email: '[email protected]', name: 'John' }
end

it 'returns false' do
expect(subject).to eq false
end

it 'doesn\'t delete the user' do
expect { subject }.not_to change { User.count }
end
end
end

describe '#save!' do
subject { user_destroy_form.save! }

context 'when the user exists' do
before do
expect(user_destroy_form).to be_valid
end

it 'returns true' do
expect(subject).to eq true
end

it 'deletes the user' do
expect { subject }.to change { User.count }.by(-1)
end
end

context 'when the user doesn\'t exist' do
let(:user_args) do
{ email: '[email protected]', name: 'John' }
end

it 'raises an exception' do
expect { subject }.to raise_error(ActiveModel::ValidationError)
end

it 'doesn\'t delete the user' do
expect { subject rescue nil }.not_to change { User.count }
end
end
end

describe '#valid?' do
subject { user_destroy_form.valid? }

it { is_expected.to be true }
end

describe '#invalid?' do
subject { user_destroy_form.invalid? }

it { is_expected.to be false }
end

describe '#errors' do
subject do
user_destroy_form.valid?
user_destroy_form.errors
end

it 'returns the correct class' do
expect(subject.class).to eq(ActiveModel::Errors)
end

it 'is empty' do
expect(subject.messages).to be_empty
end
end
end

0 comments on commit 315356a

Please sign in to comment.