Module: Ekylibre::Record::Bookkeep::ClassMethods

Defined in:
lib/ekylibre/record/bookkeep.rb

Instance Method Summary collapse

Instance Method Details

#bookkeep(options_or_klass = nil, options = {}, &block) ⇒ Object

Raises:

  • (ArgumentError)

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/ekylibre/record/bookkeep.rb', line 131

def bookkeep(options_or_klass = nil, options = {}, &block)
  klass = nil
  if block
    options = options_or_klass || options
    raise ArgumentError, "Wrong number of arguments (#{block.arity} for 1)" unless block.arity == 1
  else
    klass = options_or_klass
    implicit_bookkeeper_name = "#{self.name}Bookkeeper"
    if klass.nil? || const_defined?(implicit_bookkeeper_name)
      klass ||= const_get(implicit_bookkeeper_name)
    end
    raise ArgumentError, 'Provided class does not respond to #call method' unless klass.nil? || klass.instance_methods.include?(:call)
  end

  raise ArgumentError, 'Neither bookkeeping class nor block given' unless klass || block

  configuration = { on: Ekylibre::Record::Bookkeep.actions, column: :accounted_at, method_name: __method__ }
  configuration.update(options) if options.is_a?(Hash)
  configuration[:column] = configuration[:column].to_s
  method_name = configuration[:method_name].to_s
  core_method_name ||= "_#{method_name}_#{Ekylibre::Record::Bookkeep::Base.next_id}"

  unless columns_definition[configuration[:column]]
    Rails.logger.fatal "#{configuration[:column]} is needed for #{name}::bookkeep"
    # raise StandardError, "#{configuration[:column]} is needed for #{self.name}::bookkeep"
  end

  include Ekylibre::Record::Bookkeep::InstanceMethods

  define_method method_name do |action = :create, draft = nil|
    draft = ::Preference[:bookkeep_in_draft] if draft.nil?
    unsuppress do
      send(core_method_name, Ekylibre::Record::Bookkeep::Base.new(self, action, draft))
    end
    self.class.where(id: id).update_all(configuration[:column] => Time.zone.now)
  end

  configuration[:on] = [configuration[:on]].flatten
  Ekylibre::Record::Bookkeep.actions.each do |action|
    next unless configuration[:on].include? action
    send("after_#{action}") do
      if ::Preference[:bookkeep_automatically]
        send(method_name, action, ::Preference[:bookkeep_in_draft])
      end
      true
    end
  end

  if block
    send(:define_method, core_method_name, &block)
  else
    send(:define_method, core_method_name) { |*args|
      klass.new(*args).call
    }
  end
end