Module: ActiveRecordShards::DefaultSlavePatches

Included in:
ActiveRecord::Base
Defined in:
lib/active_record_shards/default_slave_patches.rb

Defined Under Namespace

Modules: ActiveRelationPatches, HasAndBelongsToManyPreloaderPatches, Rails41HasAndBelongsToManyBuilderExtension

Constant Summary collapse

CLASS_SLAVE_METHODS =
[ :find_by_sql, :count_by_sql,  :calculate, :find_one, :find_some, :find_every, :exists?, :table_exists? ]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/active_record_shards/default_slave_patches.rb', line 29

def self.extended(base)
  CLASS_SLAVE_METHODS.each { |m| ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(true, base, m) }

  base.class_eval do
    # fix ActiveRecord to do the right thing, and use our aliased quote_value
    def quote_value(*args, &block)
      self.class.quote_value(*args, &block)
    end

    def reload_with_slave_off(*args, &block)
      self.class.on_master { reload_without_slave_off(*args, &block) }
    end
    alias_method :reload_without_slave_off, :reload
    alias_method :reload, :reload_with_slave_off

    class << self
      def columns_with_default_slave(*args, &block)
        read_columns_from = if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
          :slave
        else
          :master
        end

        on_cx_switch_block(read_columns_from, :construct_ro_scope => false) { columns_without_default_slave(*args, &block) }
      end
      alias_method :columns_without_default_slave, :columns
      alias_method :columns, :columns_with_default_slave
    end

    class << self
      def transaction_with_slave_off(*args, &block)
        if on_slave_by_default?
          old_val = Thread.current[:_active_record_shards_slave_off]
          Thread.current[:_active_record_shards_slave_off] = true
        end

        transaction_without_slave_off(*args, &block)
      ensure
        if on_slave_by_default?
          Thread.current[:_active_record_shards_slave_off] = old_val
        end
      end

      alias_method :transaction_without_slave_off, :transaction
      alias_method :transaction, :transaction_with_slave_off
    end
  end
  if ActiveRecord::Associations.const_defined?(:HasAndBelongsToManyAssociation)
    ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, ActiveRecord::Associations::HasAndBelongsToManyAssociation, :construct_sql)
    ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, ActiveRecord::Associations::HasAndBelongsToManyAssociation, :construct_find_options!)
  end
end

.wrap_method_in_on_slave(class_method, base, method) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/active_record_shards/default_slave_patches.rb', line 4

def self.wrap_method_in_on_slave(class_method, base, method)
  base_methods = if class_method
    base.methods + base.private_methods
  else
    base.instance_methods + base.private_instance_methods
  end

  return unless base_methods.include?(method)
  _, method, punctuation = method.to_s.match(/^(.*?)([\?\!]?)$/).to_a
  base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
    #{class_method ? "class << self" : ""}
      def #{method}_with_default_slave#{punctuation}(*args, &block)
        on_slave_unless_tx do
          #{method}_without_default_slave#{punctuation}(*args, &block)
        end
      end

      alias_method :#{method}_without_default_slave#{punctuation}, :#{method}#{punctuation}
      alias_method :#{method}#{punctuation}, :#{method}_with_default_slave#{punctuation}
    #{class_method ? "end" : ""}
  RUBY
end

Instance Method Details

#on_slave_unless_tx(&block) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/active_record_shards/default_slave_patches.rb', line 82

def on_slave_unless_tx(&block)
  if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
    on_slave { yield }
  else
    yield
  end
end