acts_as_ferret does not handle transaction aborts properly. If a model
is modified but something latter causes the transaction it was wrapped
in to abort, the ferret index will not revert to the original record
data. I have included a klunky patch to defer modifying the ferret
index until after the current transaction commits. It would seem
prudent to resolve this issue, though I don''t think I have an ideal
solution.
I have an acts_as_ferret model that has indexed properties that are
derived from other models that it is associated with. As a side effect
this patch ensures that if I wrap modifications to the model and the
associated models in a transaction all the modifications to the
associated models make it into the ferret index.
Thoughts?
Index: lib/acts_as_ferret.rb
==================================================================---
lib/acts_as_ferret.rb (revision 59)
+++ lib/acts_as_ferret.rb (working copy)
@@ -496,7 +496,8 @@
module InstanceMethods
attr_reader :reindex
- @ferret_reindex = true
+ @ferret_reindex = false
+ @defer_for_transaction = false
def ferret_before_update
@ferret_reindex = true
@@ -505,9 +506,13 @@
# add to index
def ferret_create
- logger.debug "ferret_create/update: #{self.class.name} :
#{self.id}"
- self.class.ferret_index << self.to_doc if @ferret_reindex
- @ferret_reindex = true
+ unless @defer_for_transaction
+ logger.debug "ferret_create/update: #{self.class.name} :
#{self.id}"
+ self.class.ferret_index << self.to_doc if @ferret_reindex
+ @ferret_reindex = true
+ else
+ logger.debug "deferred ferret_create/update:
#{self.class.name} : #{self.id}"
+ end
true
end
alias :ferret_update :ferret_create
@@ -522,6 +527,21 @@
end
true
end
+
+ def at_start_transaction(name = nil)
+ @defer_for_transaction = true
+ end
+
+ def at_abort_transaction(name = nil)
+ @defer_for_transaction = false
+ @ferret_reindex = false
+ end
+
+ def at_commit_transaction(name = nil)
+ @defer_for_transaction = false
+ ferret_create
+ @ferret_reindex = false
+ end
# convert instance to ferret document
def to_doc
@@ -786,4 +806,28 @@
end
end
+module Transaction
+ module Simple
+ alias :start_transaction_object :start_transaction
+ alias :abort_transaction_object :abort_transaction
+ alias :commit_transaction_object :commit_transaction
+
+ def start_transaction(name = nil)
+ at_start_transaction(name) if respond_to?(:at_start_transaction)
+ start_transaction_object(name)
+ end
+
+ def abort_transaction(name = nil)
+ at_abort_transaction(name) if respond_to?(:at_abort_transaction)
+ abort_transaction_object(name)
+ end
+
+ def commit_transaction(name = nil)
+ at_commit_transaction(name) if
respond_to?(:at_commit_transaction)
+ commit_transaction_object(name)
+ end
+ end
+end
+
+
# END acts_as_ferret.rb
--
Posted via http://www.ruby-forum.com/.