Thanks for the response. The changes have no effect, I only split it up like that trying to see if I could get it to make a difference.
Thanks for the advice on the tools though, I didn't know either existed. Agile Web Development with Rails hardly mentions the console and I apparently missed what it did show. I'm definately much obliged.
I've been looking through the code(which I've posted below) trying to see what's going on and I'm finding it tough to follow, mostly because of my lack of experience with Ruby. I'm hoping someone can explain a few things to me.
I'm trying to trace the error, and it starts with the method destroy_with_transactions, which turns around and calls transaction with the method destroy_without_transactions(both of which are aliases). The thing is, there's two definitions of transaction, but with identical method signatures. I don't understand the lookup rules well enough to know which is being called, and/or why. I have Programming Ruby the pragmatic programmers guide, and I can't really find anything on it. I've also googled around and I'm still having trouble. If there's any documentation online about Ruby's lookup rules I would *really* appreciate it.
They say the best way to learn something is to dig in
Hopefully by the time this is over with I'll have a *much* more thorough understanding of Ruby/Rails.
The following is code from ActiveRecord 1.13.2 from transaction.rb minus the comments
Code:
module ActiveRecord
module Transactions # :nodoc:
TRANSACTION_MUTEX = Mutex.new
class TransactionError < ActiveRecordError # :nodoc:
end
def self.append_features(base)
super
base.extend(ClassMethods)
base.class_eval do
alias_method :destroy_without_transactions, :destroy
alias_method :destroy, :destroy_with_transactions
alias_method :save_without_transactions, :save
alias_method :save, :save_with_transactions
end
end
module ClassMethods
def transaction(*objects, &block)
previous_handler = trap('TERM') { raise TransactionError, "Transaction aborted" }
lock_mutex
begin
objects.each { |o| o.extend(Transaction::Simple) }
objects.each { |o| o.start_transaction }
result = connection.transaction(Thread.current['start_db_transaction'], &block)
objects.each { |o| o.commit_transaction }
return result
rescue Exception => object_transaction_rollback
objects.each { |o| o.abort_transaction }
raise
ensure
unlock_mutex
trap('TERM', previous_handler)
end
end
def lock_mutex#:nodoc:
Thread.current['open_transactions'] ||= 0
TRANSACTION_MUTEX.lock if Thread.current['open_transactions'] == 0
Thread.current['start_db_transaction'] = (Thread.current['open_transactions'] == 0)
Thread.current['open_transactions'] += 1
end
def unlock_mutex#:nodoc:
Thread.current['open_transactions'] -= 1
TRANSACTION_MUTEX.unlock if Thread.current['open_transactions'] == 0
end
end
def transaction(*objects, &block)
self.class.transaction(*objects, &block)
end
def destroy_with_transactions #:nodoc:
transaction { destroy_without_transactions }
end
def save_with_transactions(perform_validation = true) #:nodoc:
transaction { save_without_transactions(perform_validation) }
end
end
end
Bookmarks