Class: ActiveMerge::Service
- Inherits:
-
ActivePatterns::BaseService
- Object
- ActivePatterns::BaseService
- ActiveMerge::Service
- Includes:
- ActiveModel::Validations
- Defined in:
- lib/active_merge/service.rb
Overview
Service Object responds for merging given ActiveRecord instances into the first one
Object initializes either with ActiveRecord::Association or array of objects. If the argument is an array, then only those items taken into account, that:
-
inherited from the
ActiveRecord::Base -
persisted
-
are objects of one class
Merging algorithm
-
The item with minimal
idselected from the service argument. It will remaine intact. -
All objects, that the other items links to via “has_many” assotiation, are selected…
-
… and are rebound to the first item
-
After rebinding any item from the service argument, except the first one, to be deleted.
As a result it is only the first object from the argument remains intact, and all the instances that belonged to the other ones are now belongs to it.
Example:
# Let any kingdom has many shires and men
class Kingdom < ActiveRecord::Base
has_many :shires
has_many :men
end
class Shire < ActiveRecord::Base
belongs_to :kingdom
end
class Man < ActiveRecord::Base
belongs_to :kingdom
end
# Britain has 10 shires and 100 thousands men lives there
britain = Kingdom.create!
100000.times.each{ britain.men.create! }
10.times.each{ britain.shires.create! }
# Scotland has 5 shires and 30 thousands living men
scotland = Kingdom.create!
30000.times.each{ scotland.men.create! }
5.times.each{ scotland.shires.create! }
# Lets merge all the kingdoms:
Service.new(Kingdom.all).provide
# Now union Britain (because it is Britain that was created first)
# has all those 15 shires and 130 thousand men
# from both the old good Britain and the old good Scotland.
britain.reload.men.count # => 130000
britain.reload.shires.count # => 15
# And, alas, the Scotland Kingdom doesn't exists any more
Kingdom.find_by(scotland.id) # => nil
Warning!
The merge provided as a whole transaction. In case of any error, all changes roll back.
Let (see the example above) the shire cannot be rebount to another kingdom:
class Shire
attr_readonly :kingdom_id
end
In this case the merge won’t be finished. Not only shires, but also scots remain living in their old good Scotland!
Skipping activerecord validations
You can use the validate: false option.
With this option set any activerecord validation and callback skipped.
Service.new(Kingdom.all).provide validate: false
Defined Under Namespace
Instance Attribute Summary collapse
-
#item ⇒ Object
readonly
Returns the value of attribute item.
-
#items ⇒ Object
readonly
Returns the value of attribute items.
-
#klass ⇒ Object
readonly
Returns the value of attribute klass.
-
#klasses ⇒ Object
readonly
Returns the value of attribute klasses.
Instance Method Summary collapse
-
#initialize(list = nil) ⇒ Service
constructor
A new instance of Service.
-
#provide(options = {}) ⇒ Object
Merges all the #items to the #item as a whole transaction.
Constructor Details
#initialize(list = nil) ⇒ Service
Returns a new instance of Service.
89 90 91 92 |
# File 'lib/active_merge/service.rb', line 89 def initialize(list = nil) list = Items.new list @item, @items = list.first, Array(list[1..-1]) end |
Instance Attribute Details
#item ⇒ Object (readonly)
Returns the value of attribute item.
94 95 96 |
# File 'lib/active_merge/service.rb', line 94 def item @item end |
#items ⇒ Object (readonly)
Returns the value of attribute items.
94 95 96 |
# File 'lib/active_merge/service.rb', line 94 def items @items end |
#klass ⇒ Object (readonly)
Returns the value of attribute klass.
94 95 96 |
# File 'lib/active_merge/service.rb', line 94 def klass @klass end |
#klasses ⇒ Object (readonly)
Returns the value of attribute klasses.
94 95 96 |
# File 'lib/active_merge/service.rb', line 94 def klasses @klasses end |
Instance Method Details
#provide(options = {}) ⇒ Object
Merges all the #items to the #item as a whole transaction
98 99 100 101 102 103 104 105 |
# File 'lib/active_merge/service.rb', line 98 def provide( = {}) transaction do items.each do |item| service = SimpleService.new(self.item, item) change(service) { service.provide() } end end end |