Unidom Action 审计领域模型引擎
Unidom (UNIfied Domain Object Model) is a series of domain model engines. The Action domain model engine includes the Reason, State Transition, Obsolescene, and the Acting models. Unidom (统一领域对象模型)是一系列的领域模型引擎。审计领域模型引擎包括原因、状态迁移、废弃和行为日志的模型。
Recent Update
Check out the Road Map to find out what's the next. Check out the Change Log to find out what's new.
Usage in Gemfile
gem 'unidom-action'
Run the Database Migration
rake db:migrate
The migration versions start with 200005.
Call the Model
reason = Unidom::Action::Reason.create! activity_code: 'SRRR', name: 'broken', description: 'The box was broken.'
# SRRR = Shipment Receipt Rejection Reason
user = Unidom::Visitor::User.create!
# Create/Update/Delete the person
person = Unidom::Party::Person.create! name: 'Tim'
acting = Unidom::Action::Acting.create! actor_visitor: user, actor_party: person, reason: reason, acted: person, from_value: {}, thru_value: { name: 'Tim' }
# or the following source code do the exact same thing
acting = Unidom::Action::Acting.act! person, from: {}, thru: { name: 'Tim' }, due_to: reason, by: person, via: user, at: Time.now, action_code: 'C'
actings = Unidom::Action::Acting.acted_via(user).acted_by(person).acted_is(person).caused_by(reason)
# Update the state of the person
person.state = 'R'
person.save!
# Create a state transition to record the above change
transition = Unidom::Action::StateTransition.create! transitor_visitor: user, transitor_party: person, reason: reason, subject: person, from_state: 'C', thru_state: 'R'
# The following source code also create a state transition to record the above change
transition = Unidom::Action::StateTransition.transit! transitor_visitor: user, transitor_party: person, reason: reason, subject: person, from_state: 'C', thru_state: 'R', opened_at: Time.now
# The reason could be nil.
transitions = Unidom::Action::StateTransition.transited_via(user).transited_by(person).subject_is(subject).caused_by(reason).from_transited_to('C').thru_transited_to('R')
# Soft destroy the person
person.soft_destroy
# Create an obsolescing to record the above change
obsolescing = Unidom::Action::Obsolescing.create! obsolescer_visitor: user, obsolescer_party: person, reason: reason, obsolesced: person, obsolescence_code: 'OBSL'
# The following source code also create an obsolescing to record the above change
obsolescing = Unidom::Action::Obsolescing.obsolesce! obsolesced: person, obsolescer_visitor: user, obsolescer_party: person, reason: reason, obsolescence_code: 'OBSL', opened_at: Time.now
# The reason could be nil.
obsolescings = Unidom::Action::Obsolescing.obsolesced_via(user).obsolesced_by(person).obsolesced_is(person).caused_by(reason).obsolescence_coded_as('OBSL')
# Search the people
found_count = Unidom::Party::Person.where(name: 'Tim').count
shown_count = ... # the item count on the current page, it's calculated per found_count, page, & per_page
total_pages = ... # the total page count calculated per found_count, & per_page
@people = Unidom::Party::Person.where(name: 'Tim').paginate page: params[:page], per_page: params[:per_page]||Rails.configuration.pagination[:administration_v2_people][:per_page]
searching = Unidom::Action::Searching.search! 'people',
on: 'administration',
version: '2',
per: { name: 'Tim' },
by: current_person,
via: current_user,
displaying: 10,
of_total: 63,
on_current_page: params[:page],
of_total_page: 7,
per_page: params[:per_page]||Rails.configuration.pagination[:administration_v2_people][:per_page]
Include the Concern
include Unidom::Action::Concerns::AsActed
include Unidom::Action::Concerns::AsActorParty
include Unidom::Action::Concerns::AsObsolesced
include Unidom::Action::Concerns::AsObsolescerParty
include Unidom::Action::Concerns::AsSearcherParty
include Unidom::Action::Concerns::AsStateSubject
include Unidom::Action::Concerns::AsStateTransitorParty
As Acted concern
The As Acted concern do the following tasks for the includer automatically:
-
Define the has_many :actings macro as:
has_many :actings, class_name: 'Unidom::Action::Acting', as: :acted
-
Define the #is_acted! method as:
is_acted!(from: nil, thru: nil, due_to: nil, by: nil, via: nil, at: Time.now, action_code: 'C')
-
Define the #is_acted? method as:
is_acted?(due_to: nil, by: nil, via: nil, at: Time.now, action_code: 'C')
As Actor Party concern
The As Actor Party concern do the following tasks for the includer automatically:
-
Define the has_many :acted_actings macro as:
has_many :acted_actings, class_name: 'Unidom::Action::Acting', as: :actor_party
-
Define the #act! method as:
act!(on: nil, from: nil, thru: nil, due_to: nil, via: nil, at: Time.now, action_code: 'C')
-
Define the #act? method as:
act?(on: nil, due_to: nil, via: nil, at: Time.now, action_code: 'C')
As Caused concern
The As Caused concern do the following tasks for the includer automatically:
-
Define the belongs_to :reason macro as:
belongs_to :reason, class_name: 'Unidom::Action::Reason'
-
Define the caused_by scope as:
scope :caused_by, ->(reason) { where reason_id: to_id(reason) }
As Obsolesced concern
The As Obsolesced concern do the following tasks for the includer automatically:
-
Define the has_many :obsolescings macro as:
has_many :obsolescings, class_name: 'Unidom::Action::Obsolescing', as: :obsolesced
-
Define the #is_obsolesced! method as:
is_obsolesced!(obsolescence_code: 'OBSL', due_to: nil, via: nil, by: nil, at: Time.now)
-
Define the #is_obsolesced? method as:
is_obsolesced?(obsolescence_code: 'OBSL', due_to: nil, via: nil, by: nil, at: Time.now)
As Obsolescer Party concern
The As Obsolescer Party concern do the following tasks for the includer automatically:
-
Define the has_many :obsolesced_obsolescings macro as:
has_many :obsolesced_obsolescings, class_name: 'Unidom::Action::Obsolescing', as: :obsolescer_party
-
Define the #obsolesce! method as:
obsolesce!(it, obsolescence_code: 'OBSL', due_to: nil, via: nil, at: Time.now)
-
Define the #obsolesce? method as:
obsolesce?(it, obsolescence_code: 'OBSL', due_to: nil, via: nil, at: Time.now)
As Searcher Party concern
The As Searcher Party concern do the following tasks for the includer automatically:
-
Define the has_many :searched_searchings macro as:
has_many :searched_searchings, class_name: 'Unidom::Action::Searching', as: :searcher_party
-
Define the #search! method as:
search!(it, on: '', version: '1', per: {}, due_to: nil, via: nil, at: Time.now, displaying: 0, of_total: 0, on_current_page: 0, of_total_page: 0, per_page: 0)
-
Define the #search? method as:
search?(it, on: '', version: '1', due_to: nil, at: Time.now)
As State Subject concern
The As State Subject concern do the following tasks for the includer automatically:
-
Define the has_many :state_transitions macro as:
has_many :state_transitions, class_name: 'Unidom::Action::StateTransition', as: :subject
-
Define the #is_transited! method as:
is_transited!(from: nil, thru: nil, due_to: nil, via: nil, by: nil, at: Time.now)
-
Define the #is_transited? method as:
is_transited?(from: nil, thru: nil, due_to: nil, via: nil, by: nil, at: Time.now)
As State Transitor Party concern
The As State Transitor Party concern do the following tasks for the includer automatically:
-
Define the has_many :transited_state_transitions macro as:
has_many :transited_state_transitions, class_name: 'Unidom::Action::StateTransition', as: :transitor_party
-
Define the #transit! method as:
transit!(it, from: nil, thru: nil, due_to: nil, via: nil, at: Time.now)
-
Define the #transit? method as:
transit?(it, from: nil, thru: nil, due_to: nil, via: nil, at: Time.now)
Enum codes
Obsolescence enum code
Unidom::Action::Obsolescence::OBSOLESCE
Unidom::Action::Obsolescence::RECOVER
Action enum code
Unidom::Action::Action::CREATE
Unidom::Action::Action::DESTROY
Unidom::Action::Action::INDEX
Unidom::Action::Action::SHOW
Unidom::Action::Action::UPDATE
Disable the Model & Migration
If you only need the app components other than models, the migrations should be neglected, and the models should not be loaded.
# config/initializers/unidom.rb
Unidom::Common.configure do |options|
options[:neglected_namespaces] = %w{
Unidom::Action
}
end
RSpec examples
RSpec example manifest (run automatically)
# spec/models/unidom_spec.rb
require 'unidom/action/models_rspec'
# spec/types/unidom_spec.rb
require 'unidom/action/types_rspec'
# spec/validators/unidom_spec.rb
require 'unidom/action/validators_rspec'
RSpec shared examples (to be integrated)
# app/models/your_acted.rb
class YourActed < ApplicationRecord
include Unidom::Common::Concerns::ModelExtension
include Unidom::Action::Concerns::AsActed
end
# app/models/your_actor_party.rb
class YourActorParty < ApplicationRecord
include Unidom::Common::Concerns::ModelExtension
include Unidom::Action::Concerns::AsActorParty
end
# The Unidom::Action::Acting model, the Unidom::Action::Obsolescing model, the Unidom::Action::Searching model, & the Unidom::Action::StateTransition model already include the Unidom::Action::Concerns::AsCaused concern
# app/models/your_caused.rb
class YourCaused < ApplicationRecord
include Unidom::Common::Concerns::ModelExtension
include Unidom::Action::Concerns::AsCaused
end
# app/models/your_obsolesced.rb
class YourObsolesced < ApplicationRecord
include Unidom::Common::Concerns::ModelExtension
include Unidom::Action::Concerns::AsObsolesced
end
# app/models/your_obsolescer_party.rb
class YourObsolescerParty < ApplicationRecord
include Unidom::Common::Concerns::ModelExtension
include Unidom::Action::Concerns::AsObsolescerParty
end
# app/models/your_searcher_party.rb
class YourSearcherParty < ApplicationRecord
include Unidom::Common::Concerns::ModelExtension
include Unidom::Action::Concerns::AsSearcherParty
end
# app/models/your_state_subject.rb
class YourStateSubject < ApplicationRecord
include Unidom::Common::Concerns::ModelExtension
include Unidom::Action::Concerns::AsStateSubject
end
# app/models/your_state_transitor_party.rb
class YourStateTransitorParty < ApplicationRecord
include Unidom::Common::Concerns::ModelExtension
include Unidom::Action::Concerns::AsStateTransitorParty
end
# spec/support/unidom_rspec_shared_examples.rb
require 'unidom/action/rspec_shared_examples'
# spec/models/your_acted_spec.rb
describe YourActed, type: :model do
context do
model_attribtues = {
your_attribute: 'your value'
}
actor_party = Unidom::Party::Person.create! name: 'Tim'
actor_visitor = Unidom::Visitor::User.create!
it_behaves_like 'Unidom::Action::Concerns::AsActed', model_attributes, actor_party, actor_visitor
end
end
# spec/models/your_actor_party_spec.rb
describe YourActorParty, type: :model do
context do
model_attribtues = {
your_attribute: 'your value'
}
acted_attributes = {}
acted = Unidom::Visitor::User.create! acted_attributes
actor_visitor_attributes = {}
actor_visitor = Unidom::Visitor::User.create! actor_visitor_attributes
it_behaves_like 'Unidom::Action::Concerns::AsActorParty', model_attributes, acted, actor_visitor
end
end
# spec/models/your_caused_spec.rb
describe YourCaused, type: :model do
context do
model_attribtues = {
your_attribute: 'your value'
}
it_behaves_like 'Unidom::Action::Concerns::AsCaused', model_attribtues
end
end
# spec/models/your_obsolesced_spec.rb
describe YourObsolesced, type: :model do
context do
model_attribtues = {
your_attribute: 'your value'
}
obsolescer_party_attributes = {
name: 'Tim'
}
obsolescer_party = Unidom::Party::Person.create! obsolescer_party_attributes
obsolescer_visitor_attributes = {}
obsolescer_visitor = Unidom::Visitor::User.create! obsolescer_visitor_attributes
it_behaves_like 'Unidom::Action::Concerns::AsObsolesced', model_attributes, obsolescer_party, obsolescer_visitor
end
end
# spec/models/your_obsolescer_party_spec.rb
describe YourObsolescerParty, type: :model do
context do
model_attribtues = {
your_attribute: 'your value'
}
it_behaves_like 'Unidom::Action::Concerns::AsObsolescerParty', model_attribtues
end
end
# spec/models/your_searcher_party_spec.rb
describe YourSearcherParty, type: :model do
context do
model_attribtues = {
your_attribute: 'your value'
}
it_behaves_like 'Unidom::Action::Concerns::AsSearcherParty', model_attribtues
end
end
# spec/models/your_state_subject_spec.rb
describe YourStateSubject, type: :model do
context do
model_attribtues = {
your_attribute: 'your value'
}
it_behaves_like 'Unidom::Action::Concerns::AsStateSubject', model_attribtues
end
end
# spec/models/your_state_transitor_party_spec.rb
describe YourAsStateTransitorParty, type: :model do
context do
model_attribtues = {
your_attribute: 'your value'
}
it_behaves_like 'Unidom::Action::Concerns::YourAsStateTransitorParty', model_attribtues
end
end