Module: Ekylibre::Record::Sums::ClassMethods

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

Instance Method Summary collapse

Instance Method Details

#sums(target, children, *args) ⇒ Object

Sums columns and puts result in “Parent” table without validations or callbacks.


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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/ekylibre/record/sums.rb', line 9

def sums(target, children, *args)
  options = args.extract_options!
  args.each do |arg|
    if arg.is_a?(Symbol) || arg.is_a?(String)
      options[arg.to_sym] = arg.to_sym
    elsif arg.is_a? Hash
      options.merge!(arg)
    else
      raise ArgumentError, "Unvalid type #{arg.inspect}:#{arg.class.name}"
    end
  end
  method_name = options.delete(:method) || "sums_#{children}_of_#{target}"
  target_reflection = reflect_on_association(target)
  target_id = target_reflection.foreign_key.to_sym
  record = children.to_s.singularize
  code = ''

  callbacks = options.delete(:callbacks) || [:after_save, :after_destroy]
  for callback in callbacks
    code << "#{callback} :#{method_name}\n"
  end

  from = options.delete(:from)
  negate = options.delete(:negate)

  code << "def #{method_name}\n"
  code << "  return unless self.#{target}\n"
  code << '  ' + options.values.join(' = ') + " = 0\n"
  code << "  self.#{target}.reload\n"
  # code << "  #{self.name}.where(#{target_id}: self.#{target_id}).find_each do |#{record}|\n"
  # code << "  #{self.name}.where(#{target_id}: self.#{target_id}).find_each do |#{record}|\n"
  code << "  #{target}.#{children}.find_each do |#{record}|\n"
  options.each do |k, v|
    code << '    x = ' + (k.is_a?(Symbol) ? "#{record}.#{k}" : k) + "#{from ? '.to_s.to_f' : ''}\n"
    code << "    if x.nil?\n"
    code << "      Rails.logger.warn 'Nil value in sums'\n"
    code << "      x = 0.0\n"
    code << "    end\n"
    code += if negate
              "    #{v} -= x\n"
            else
              "    #{v} += x\n"
            end
  end
  code << "  end\n"
  # code << "  " + Ekylibre::Schema.references(self.name.underscore.to_sym, target_id).to_s.camelcase + ".where(id: self.#{target_id}).update_all(" + options.collect{|k, v| "#{v}: #{v}"}.join(", ") + ")\n"
  # code << "  " + target_reflection.class_name + ".where(id: self.#{target_id}).update_all(" + options.collect{|k, v| "#{v}: #{v}"}.join(", ") + ")\n"
  code << "  #{target}.update_columns(" + options.values.collect { |v| "#{v}: #{v}" }.join(', ') + ")\n"
  code << "end\n"

  # code.split("\n").each_with_index{|l, x| puts((x+1).to_s.rjust(4)+": "+l)}

  class_eval code
end