Skip to content

sergeyantonov1/transaction

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,301 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Transaction

Simple example using transactions with ActiveRecord::Base.transaction

Scripts

  • bin/setup - setup required gems and migrate db if needed
  • bin/quality - runs rubocop, brakeman, rails_best_practices and bundle-audit for the app
  • bin/ci - should be used in the CI or locally
  • bin/server - to run server locally

Example

app/interactors/make_payment.rb

class MakePayment
  include Interactor

  delegate :user_from, :user_to, :amount, to: :context

  def call
    ActiveRecord::Base.transaction do
      user_from.update!(balance: user_from.balance - amount)
      user_to.update!(balance: user_to.balance + amount)

      create_transaction
    end

  rescue ActiveRecord::RecordInvalid => e
    context.fail!(error: e.message)
  end

  private

  def create_transaction
    Transaction.create!(
      user_from: user_from,
      user_to: user_to,
      amount: amount
    )
  end
end

Testing

spec/interactors/make_payment_spec.rb

require "rails_helper"

describe MakePayment do
  describe "#call" do
    let(:amount) { 10 }
    let(:user_to) { create :user, balance: 0 }

    subject(:result) do
      described_class.call(
        user_from: user_from,
        user_to: user_to,
        amount: amount
      )
    end

    context "when the sender's balance is zero" do
      let(:user_from) { create :user, balance: 0 }

      it "doesn't create a transaction" do
        expect { result }.to change(Transaction, :count).by(0)
      end

      it "doesn't update user balance" do
        expect(result.user_from.reload.balance).to eq(0)
        expect(result.user_to.reload.balance).to eq(0)
        expect(result.error).to eq("Validation failed: Balance must be greater than or equal to 0.0")
      end
    end

    context "when the sender's balance is greater than or equal to zero" do
      let(:user_from) { create :user, balance: 20 }

      it "creates a transaction" do
        expect { result }.to change(Transaction, :count).by(1)
      end

      it "updates user balances" do
        expect(result.user_from.balance).to eq(10)
        expect(result.user_to.balance).to eq(10)
      end
    end
  end
end

About

Simple example using transactions with ActiveRecord::Base.transaction

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors