module ArelExtensions::Math

Public Instance Methods

+(other) click to toggle source

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.

# File lib/arel_extensions/math.rb, line 17
def +(other)
  case self
    when Arel::Nodes::Quoted
      return self.concat(other)
    when Arel::Nodes::Grouping
      if self.expr.left.is_a?(String) || self.expr.right.is_a?(String)
        return self.concat(other)
      else
        return Arel.grouping(Arel::Nodes::Addition.new self, other)
      end
    when ArelExtensions::Nodes::Function, ArelExtensions::Nodes::Case
      return 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 = Arel.column_of(self.relation.table_name, self.name.to_s) if self.respond_to?(:relation)
    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) click to toggle source

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

# File lib/arel_extensions/math.rb, line 63
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 = Arel.column_of(self.relation.table_name, self.name.to_s)
    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 = Arel.column_of(other.relation.table_name, other.name.to_s)
          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