Module: ArelExtensions::Math

Instance Method Summary collapse

Instance Method Details

#+(other) ⇒ Object

function + between String and others (convert in string) allows you to concatenate 2 or more strings together. Date and integer adds or subtracts a specified time interval from a date.



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
63
64
# File 'lib/arel_extensions/math.rb', line 17

def +(other)
  case self
  when Arel::Nodes::Quoted
    self.concat(other)
  when Arel::Nodes::Grouping
    if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
      self.concat(other)
    else
      Arel.grouping(Arel::Nodes::Addition.new self, other)
    end
  when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
    case self.return_type
    when :string, :text
      self.concat(other)
    when :integer, :decimal, :float, :number, :int
      Arel.grouping(Arel::Nodes::Addition.new self, other)
    when :date, :datetime
      ArelExtensions::Nodes::DateAdd.new [self, other]
    else
      self.concat(other)
    end
  when Arel::Nodes::Function
    Arel.grouping(Arel::Nodes::Addition.new self, other)
  else
    col =
      if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
        self.type_caster
      else
        Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
      end
    if !col # if the column doesn't exist in the database
      Arel.grouping(Arel::Nodes::Addition.new(self, Arel.quoted(other)))
    else
      arg = col.type
      if arg == :integer || !arg
        other = other.to_i if other.is_a?(String)
        Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
      elsif arg == :decimal || arg == :float
        other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
        Arel.grouping(Arel::Nodes::Addition.new self, Arel.quoted(other))
      elsif arg == :datetime || arg == :date
        ArelExtensions::Nodes::DateAdd.new [self, other]
      elsif arg == :string || arg == :text
        self.concat(other)
      end
    end
  end
end

#-(other) ⇒ Object

function returns the time between two dates function returns the substraction between two ints



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/arel_extensions/math.rb', line 68

def -(other)
  case self
  when Arel::Nodes::Grouping
    if self.expr.left.is_a?(Date) || self.expr.left.is_a?(DateTime)
      Arel.grouping(ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)])
    else
      Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
    end
  when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
    case self.return_type
    when :string, :text # ???
      Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other))) # ??
    when :integer, :decimal, :float, :number
      Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
    when :date, :datetime
      ArelExtensions::Nodes::DateSub.new [self, Arel.quoted(other)]
    else
      Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
    end
  when Arel::Nodes::Function
    Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
  else
    col =
      if self.is_a?(Arel::Attribute) && self.respond_to?(:type_caster) && self.able_to_type_cast?
        self.type_caster
      else
        Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
      end
    if !col # if the column doesn't exist in the database
      Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
    else
      arg = col.type
      if (arg == :date || arg == :datetime)
        case other
        when Arel::Attributes::Attribute
          col2 =
            if other.is_a?(Arel::Attribute) && other.respond_to?(:type_caster) && other.able_to_type_cast?
              other.type_caster
            else
              Arel.column_of(other.relation.table_name, other.name.to_s) if other.respond_to?(:relation)
            end
          if !col2 # if the column doesn't exist in the database
            ArelExtensions::Nodes::DateSub.new [self, other]
          else
            arg2 = col2.type
            if arg2 == :date || arg2 == :datetime
              ArelExtensions::Nodes::DateDiff.new [self, other]
            else
              ArelExtensions::Nodes::DateSub.new [self, other]
            end
          end
        when Arel::Nodes::Node, DateTime, Time, String, Date
          ArelExtensions::Nodes::DateDiff.new [self, other]
        when ArelExtensions::Nodes::Duration, Integer
          ArelExtensions::Nodes::DateSub.new [self, other]
        else # ActiveSupport::Duration
          ArelExtensions::Nodes::DateAdd.new [self, -other]
        end
      else
        case other
        when Integer, Float, BigDecimal
          Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.sql(other.to_s)))
        when String
          Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.sql(other)))
        else
          Arel.grouping(Arel::Nodes::Subtraction.new(self, Arel.quoted(other)))
        end
      end
    end
  end
end