Last active
August 29, 2015 14:11
-
-
Save rosiehoyem/3a068619ee9056af6fac to your computer and use it in GitHub Desktop.
Ruby Transactions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Person < ActiveRecord::Base | |
... | |
def destroy_door_access | |
if self.door_accesses.first | |
self.door_accesses.first.destroy | |
else | |
true | |
end | |
end | |
def remove_location | |
self.location_id = nil | |
end | |
def destroy_authorizations | |
if self.authorizations.first | |
self.authorizations.each {|authorization| authorization.destroy} | |
else | |
true | |
end | |
end | |
def update_historical | |
self.current_employee = nil | |
self.terminated_date = Date.today | |
end | |
def convert_to_historical | |
transaction do | |
update_historical | |
destroy_door_access | |
remove_location | |
destroy_authorizations | |
save | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def convert_to_historical | |
transaction do | |
update_historical | |
destroy_door_access | |
remove_location | |
destroy_authorizations | |
save | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
describe Person do | |
it "is invalid without a first name" do | |
person = FactoryGirl.build(:person, first_name: nil) | |
person.save | |
expect(person.errors.count).to eq(1) | |
end | |
it "is invalid without a last name" do | |
person = FactoryGirl.build(:person, last_name: nil) | |
person.save | |
expect(person.errors.count).to eq(1) | |
end | |
it "updates current_employee and terminated_date" do | |
person = FactoryGirl.create(:person, current_employee: true, terminated_date: nil) | |
door_access = person.door_accesses.create! | |
person.update_historical | |
expect(person.current_employee).to eq(false) | |
expect(person.terminated_date).to eq(Date.today) | |
end | |
it "destroys door access" do | |
person = FactoryGirl.create(:person) | |
door_access = person.door_accesses.create! | |
person.destroy_door_access | |
expect(person.door_accesses.first).to eq(nil) | |
end | |
it "destroys authorizations" do | |
person = FactoryGirl.create(:person) | |
permission = FactoryGirl.create(:permission) | |
authorization = person.authorizations.create!(permission_id: 1, read: true, write: true) | |
person.destroy_authorizations | |
expect(person.authorizations.count).to eq(0) | |
end | |
it "remove locations" do | |
person = FactoryGirl.create(:person) | |
location = FactoryGirl.create(:location) | |
person.location_id = 1 | |
person.remove_location | |
expect(person.location_id).to eq(nil) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
it "completes full historical transaction historical transaction" do | |
person = FactoryGirl.create(:person, current_employee: true, terminated_date: nil) | |
door_access = person.door_accesses.create! | |
permission = FactoryGirl.create(:permission) | |
authorization = person.authorizations.create(permission_id: permission.id, read: true, write: true) | |
location = FactoryGirl.create(:location) | |
person.location_id = 1 | |
person.convert_to_historical | |
expect(person.current_employee).to eq(false) | |
expect(person.terminated_date).to eq(Date.today) | |
expect(person.door_accesses.count).to eq(0) | |
expect(person.location_id).to eq(nil) | |
expect(person.authorizations.count).to eq(0) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Recently I built a features for ACE, the application our admin staff uses to manage just about everything for the MPC. They requested a simple way to turn a person from a current employee into a past, or historical person in our system. To move someone from one status to the other, could include having to touch almost every module in the application. For example, the person's door access needs to be deleted, the location of their office will need to removed, and a terminated date will need to be recorded among other things. If some of these steps are completed, but not others, it would serve to severely confuse both the staff and the application. This seemed like a good candidate for a transaction. | |
The classic transaction example is of a financial transaction where one side of the transaction should not be recorded unless the other is also successfully completed. If the second part fails, the whole thing should roll back. | |
[code language="ruby"] | |
balance.transaction do | |
balance.save! | |
account.save! | |
end | |
[/code] | |
To create the "Historical Button" feature for ACE, I decided to create several small, reuseable methods each capturing one aspect of moving an employee from current to historical. Here are the tests: | |
[code language="ruby"] | |
[/code] | |
Then I wrote the methods: | |
[code language="ruby"] | |
[/code] | |
Then I wrapped these methods in a transaction. The test: | |
[code language="ruby"] | |
transaction do | |
end | |
[/code] | |
And the code: | |
[code language="ruby"] | |
transaction do | |
end | |
[/code] | |
This is, admittedly, a very simple implementation of a transaction. After digging into the documentation a bit, it appears the complexity of these when dealing with distributed systems... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment