Module: Gourami::Extensions::Changes::ClassMethods

Defined in:
lib/gourami/extensions/changes.rb

Instance Method Summary collapse

Instance Method Details

#attribute(name, options = {}, &default_block) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/gourami/extensions/changes.rb', line 7

def attribute(name, options = {}, &default_block)
  super.tap do
    watch_changes = options.fetch(:watch_changes, false)

    if watch_changes
      mixin = Module.new do |mixin|
        mixin.send(:define_method, :"_#{name}=") do |value|
          super(value).tap do
            new_value = instance_variable_get(:"@#{name}")
            attribute_did_change = if watch_changes.respond_to?(:call)
              instance_exec(new_value, &watch_changes)
            elsif !defined?(record)
              raise ConfigurationError, "Default `watch_changes` behavior not available without a `record`. Try `attribute(:#{name}, :watch_changes => ->(new_value) { new_value != custom_check_logic )`"
            elsif record.nil?
              !new_value.nil?
            else
              record.send(name) != new_value
            end

            unless WATCH_CHANGES_VALID_RETURN_VALUES.include?(attribute_did_change)
              raise WatchChangesError, "`watch_changes` block for `#{name.inspect}` must return one of #{WATCH_CHANGES_VALID_RETURN_VALUES.inspect}."
            end

            did_change(name, attribute_did_change)
          end
        end
        mixin.send(:private, :"_#{name}=")
      end
      include(mixin)
    end
  end
end