Module: ArelExtensions

Defined in:
lib/arel_extensions/visitors/oracle.rb,
lib/arel_extensions/math.rb,
lib/arel_extensions/aliases.rb,
lib/arel_extensions/helpers.rb,
lib/arel_extensions/railtie.rb,
lib/arel_extensions/version.rb,
lib/arel_extensions/nodes/abs.rb,
lib/arel_extensions/nodes/md5.rb,
lib/arel_extensions/nodes/std.rb,
lib/arel_extensions/nodes/sum.rb,
lib/arel_extensions/attributes.rb,
lib/arel_extensions/nodes/case.rb,
lib/arel_extensions/nodes/cast.rb,
lib/arel_extensions/nodes/ceil.rb,
lib/arel_extensions/nodes/json.rb,
lib/arel_extensions/nodes/rand.rb,
lib/arel_extensions/nodes/then.rb,
lib/arel_extensions/nodes/trim.rb,
lib/arel_extensions/nodes/wday.rb,
lib/arel_extensions/comparators.rb,
lib/arel_extensions/nodes/blank.rb,
lib/arel_extensions/nodes/floor.rb,
lib/arel_extensions/nodes/log10.rb,
lib/arel_extensions/nodes/power.rb,
lib/arel_extensions/nodes/round.rb,
lib/arel_extensions/nodes/union.rb,
lib/arel_extensions/nodes/format.rb,
lib/arel_extensions/nodes/length.rb,
lib/arel_extensions/nodes/locate.rb,
lib/arel_extensions/nodes/repeat.rb,
lib/arel_extensions/predications.rb,
lib/arel_extensions/date_duration.rb,
lib/arel_extensions/nodes/collate.rb,
lib/arel_extensions/nodes/is_null.rb,
lib/arel_extensions/nodes/matches.rb,
lib/arel_extensions/nodes/replace.rb,
lib/arel_extensions/nodes/soundex.rb,
lib/arel_extensions/set_functions.rb,
lib/arel_extensions/insert_manager.rb,
lib/arel_extensions/math_functions.rb,
lib/arel_extensions/nodes/coalesce.rb,
lib/arel_extensions/nodes/duration.rb,
lib/arel_extensions/nodes/function.rb,
lib/arel_extensions/null_functions.rb,
lib/arel_extensions/visitors/mssql.rb,
lib/arel_extensions/visitors/mysql.rb,
lib/arel_extensions/nodes/date_diff.rb,
lib/arel_extensions/nodes/substring.rb,
lib/arel_extensions/nodes/union_all.rb,
lib/arel_extensions/visitors/ibm_db.rb,
lib/arel_extensions/visitors/sqlite.rb,
lib/arel_extensions/visitors/to_sql.rb,
lib/arel_extensions/string_functions.rb,
lib/arel_extensions/boolean_functions.rb,
lib/arel_extensions/nodes/change_case.rb,
lib/arel_extensions/nodes/find_in_set.rb,
lib/arel_extensions/visitors/oracle12.rb,
lib/arel_extensions/visitors/postgresql.rb,
lib/arel_extensions/common_sql_functions.rb,
lib/arel_extensions/nodes/formatted_date.rb,
lib/arel_extensions/nodes/formatted_number.rb,
lib/arel_extensions/visitors/convert_format.rb,
lib/arel_extensions/nodes/aggregate_function.rb,
lib/arel_extensions/nodes/levenshtein_distance.rb

Overview

require ‘oracle_visitor’

Defined Under Namespace

Modules: Aliases, Attributes, BooleanFunctions, Comparators, DateDuration, InsertManager, Math, MathFunctions, Nodes, NullFunctions, Predications, SetFunctions, StringFunctions, Visitors Classes: CommonSqlFunctions, Railtie

Constant Summary collapse

VERSION =
'2.2.1'.freeze

Class Method Summary collapse

Class Method Details

.column_of(table_name, column_name) ⇒ Object



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
# File 'lib/arel_extensions/helpers.rb', line 28

def self.column_of(table_name, column_name)
  pool = ActiveRecord::Base.connection.pool
  use_arel_table = !ActiveRecord::Base.connected? || \
    (pool.respond_to?(:schema_cache) && pool.schema_cache.nil?)

  if use_arel_table
    column_of_via_arel_table(table_name, column_name)
  else
    if pool.respond_to?(:pool_config)
      if pool.pool_config.respond_to?(:schema_reflection) # activerecord >= 7.1
        if ActiveRecord.version >= Gem::Version.create('7.2')
          pool.pool_config.schema_reflection.columns_hash(pool, table_name)[column_name]
        else
          pool.pool_config.schema_reflection.columns_hash(ActiveRecord::Base.connection, table_name)[column_name]
        end
      else # activerecord < 7.1
        pool.pool_config.schema_cache.columns_hash(table_name)[column_name]
      end
    elsif pool.respond_to?(:schema_cache) # activerecord < 6.1
      pool.schema_cache.columns_hash(table_name)[column_name]
    else # activerecord < 5.0
      column_of_via_arel_table(table_name, column_name)
    end
  end
rescue ActiveRecord::ConnectionNotEstablished
  column_of_via_arel_table(table_name, column_name)
rescue ActiveRecord::StatementInvalid
  nil
rescue => e
  warn("Warning: Unexpected exception caught while fetching column name for #{table_name}.#{column_name} in `column_of`")
  warn(e)
  warn(e.backtrace)
  nil
end

.column_of_via_arel_table(table_name, column_name) ⇒ Object

column_of

Before the creation of these methods, getting the column name was done uniquely through the code found in ‘column_of_via_arel_table`.

This turned out to be unreliable, most notably when using adapters that do not come with activerecord standard batteries. SQL Server is the most notorious example.

Currently, we’re using a needlessly complicated way to address this issue. Different versions of activerecord are behaving differently; the public APIs do not seem to come with any guarantees, so we need to be sure that we’re coveing all these cases.



18
19
20
21
22
23
24
25
26
# File 'lib/arel_extensions/helpers.rb', line 18

def self.column_of_via_arel_table(table_name, column_name)
  Arel::Table.engine.connection.schema_cache.columns_hash(table_name)[column_name]
rescue NoMethodError
  nil
rescue => e
  warn("Warning: Unexpected exception caught while fetching column name for #{table_name}.#{column_name} in `column_of_via_arel_table`\n#{e.class}")
  warn(e.backtrace)
  nil
end