Skip to content

Instantly share code, notes, and snippets.

@lifo
Created September 20, 2009 15:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lifo/189829 to your computer and use it in GitHub Desktop.
Save lifo/189829 to your computer and use it in GitHub Desktop.
module SetupOnce
def self.included(base)
base.class_eval do
attr_accessor :copy_ivars_blocks, :copy_ivars_binding, :copy_ivar_names
alias_method_chain :run_current_setup_blocks, :copy_ivars
alias_method_chain :initialize, :copy_ivars
alias_method_chain :build, :copy_ivars
end
end
def initialize_with_copy_ivars(name, parent, &blk)
Shoulda.add_context(self)
self.copy_ivars_blocks = []
self.copy_ivar_names = []
self.copy_ivars_binding = nil
Shoulda.remove_context
initialize_without_copy_ivars(name, parent, &blk)
end
def copy_ivars(&blk)
self.copy_ivars_blocks << blk
end
def build_with_copy_ivars
self.shoulds.unshift({:name => 'start transaction', :before => nil, :block => proc { @shoulda_context.start_db_transaction } })
self.shoulds.push({:name => 'stop transaction', :before => nil, :block => proc { @shoulda_context.stop_db_transaction } })
build_without_copy_ivars
end
def run_current_setup_blocks_with_copy_ivars(binding)
if self.copy_ivar_names.blank?
self.copy_ivars_binding = binding.clone
self.copy_ivars_blocks.map {|ci| ci.bind(self.copy_ivars_binding).call}
self.copy_ivar_names = self.copy_ivars_binding.instance_variables
end
self.copy_ivar_names.each do |ivar|
original = self.copy_ivars_binding.instance_variable_get(ivar)
binding.instance_variable_set(ivar, original)
end
run_current_setup_blocks_without_copy_ivars(binding)
end
def start_db_transaction
::ActiveRecord::Base.connection.increment_open_transactions
::ActiveRecord::Base.connection.transaction_joinable = false
::ActiveRecord::Base.connection.begin_db_transaction
end
def stop_db_transaction
if ::ActiveRecord::Base.connection.open_transactions != 0
::ActiveRecord::Base.connection.rollback_db_transaction
::ActiveRecord::Base.connection.decrement_open_transactions
end
end
end
Shoulda::Context.send :include, SetupOnce
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment