Module: ActiveRecord::VirtualAttributes::ClassMethods

Defined in:
lib/active_record/virtual_attributes.rb

Instance Method Summary collapse

Instance Method Details

#attribute_typesObject



105
106
107
108
109
110
111
112
113
# File 'lib/active_record/virtual_attributes.rb', line 105

def attribute_types
  @attribute_types || super.tap do |hash|
    virtual_attributes_to_define.each do |name, (type, options)|
      type = type.call if type.respond_to?(:call)
      type = ActiveRecord::Type.lookup(type, **options) if type.kind_of?(Symbol)
      hash[name] = type
    end
  end
end

#define_virtual_attribute(name, cast_type) ⇒ Object



115
116
117
# File 'lib/active_record/virtual_attributes.rb', line 115

def define_virtual_attribute(name, cast_type)
  attribute_types[name.to_s] = cast_type
end

#virtual_attribute(name, type, through: nil, uses: nil, arel: nil, source: name, default: nil, **options) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/active_record/virtual_attributes.rb', line 59

def virtual_attribute(name, type, through: nil, uses: nil, arel: nil, source: name, default: nil, **options)
  name = name.to_s
  reload_schema_from_cache

  self.virtual_attributes_to_define =
    virtual_attributes_to_define.merge(name => [type, options])

  if through
    define_delegate(name, source, :to => through, :allow_nil => true, :default => default)

    unless (to_ref = reflection_with_virtual(through))
      raise ArgumentError, "#{self.name}.virtual_attribute #{name.inspect} references unknown :through association #{through.inspect}"
    end

    # ensure that the through table is in the uses clause
    uses = merge_includes({through => {}}, uses)

    # We can not validate target#source exists
    #   Because we may not have loaded the class yet
    #   And we definitely have not loaded the database yet
    arel ||= virtual_delegate_arel(source, to_ref)
  end

  define_virtual_include(name, uses)
  define_virtual_arel(name, arel)
end

#virtual_attribute?(name) ⇒ Boolean

Introspection

Returns:

  • (Boolean)


90
91
92
93
94
95
# File 'lib/active_record/virtual_attributes.rb', line 90

def virtual_attribute?(name)
  has_attribute?(name) && (
    !respond_to?(:column_for_attribute) ||
    column_for_attribute(name).kind_of?(ActiveRecord::ConnectionAdapters::NullColumn)
  )
end

#virtual_attribute_namesObject



97
98
99
100
101
102
103
# File 'lib/active_record/virtual_attributes.rb', line 97

def virtual_attribute_names
  if respond_to?(:column_names)
    attribute_names - column_names
  else
    attribute_names
  end
end

#virtual_column(name, type:, **options) ⇒ Object

Compatibility method: virtual_attribute is a more accurate name



55
56
57
# File 'lib/active_record/virtual_attributes.rb', line 55

def virtual_column(name, type:, **options)
  virtual_attribute(name, type, **options)
end