Module: ColumnsOnDemand::InstanceMethods

Defined in:
lib/columns_on_demand.rb

Instance Method Summary collapse

Instance Method Details

#_read_attribute(attr_name, &block) ⇒ Object



99
100
101
102
# File 'lib/columns_on_demand.rb', line 99

def _read_attribute(attr_name, &block)
  ensure_loaded(attr_name)
  super(attr_name, &block)
end

#attribute_changed_in_place?(attr_name) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/columns_on_demand.rb', line 85

def attribute_changed_in_place?(attr_name)
  column_loaded?(attr_name) && super(attr_name)
end

#attribute_namesObject



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

def attribute_names
  (super + columns_to_load_on_demand).uniq.sort
end

#attributesObject



50
51
52
53
# File 'lib/columns_on_demand.rb', line 50

def attributes
  load_attributes(*columns_to_load_on_demand.reject {|attr_name| column_loaded?(attr_name)})
  super
end

#changed_in_place?(attr_name) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/columns_on_demand.rb', line 81

def changed_in_place?(attr_name)
  column_loaded?(attr_name) && super(attr_name)
end

#column_loaded?(attr_name) ⇒ Boolean

Returns:

  • (Boolean)


46
47
48
# File 'lib/columns_on_demand.rb', line 46

def column_loaded?(attr_name)
  !columns_to_load_on_demand.include?(attr_name) || @attributes.key?(attr_name) || new_record? || columns_loaded.include?(attr_name)
end

#columns_loadedObject



42
43
44
# File 'lib/columns_on_demand.rb', line 42

def columns_loaded
  @columns_loaded ||= Set.new
end

#ensure_loaded(attr_name) ⇒ Object



77
78
79
# File 'lib/columns_on_demand.rb', line 77

def ensure_loaded(attr_name)
  load_attributes(attr_name.to_s) unless column_loaded?(attr_name.to_s)
end

#load_attributes(*attr_names) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/columns_on_demand.rb', line 59

def load_attributes(*attr_names)
  return if attr_names.blank?

  values = self.class.connection.select_rows(
    "SELECT #{attr_names.collect {|attr_name| self.class.connection.quote_column_name(attr_name)}.join(", ")}" +
    "  FROM #{self.class.quoted_table_name}" +
    " WHERE #{self.class.connection.quote_column_name(self.class.primary_key)} = #{self.class.connection.quote(id)}")
  row = values.first || raise(ActiveRecord::RecordNotFound, "Couldn't find #{self.class.name} with ID=#{id}")

  attr_names.each_with_index do |attr_name, i|
    columns_loaded << attr_name
    value = row[i]

    # activerecord 4.2 or later, which make it easy to replicate the normal typecasting and deserialization logic
    @attributes.write_from_database(attr_name, value)
  end
end

#missing_attribute(attr_name, *args) ⇒ Object



104
105
106
107
108
109
110
# File 'lib/columns_on_demand.rb', line 104

def missing_attribute(attr_name, *args)
  if columns_to_load_on_demand.include?(attr_name)
    load_attributes(attr_name)
  else
    super(attr_name, *args)
  end
end

#read_attribute(attr_name, &block) ⇒ Object



89
90
91
92
# File 'lib/columns_on_demand.rb', line 89

def read_attribute(attr_name, &block)
  ensure_loaded(attr_name)
  super(attr_name, &block)
end

#read_attribute_before_type_cast(attr_name) ⇒ Object



94
95
96
97
# File 'lib/columns_on_demand.rb', line 94

def read_attribute_before_type_cast(attr_name)
  ensure_loaded(attr_name)
  super(attr_name)
end

#reload(*args) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/columns_on_demand.rb', line 112

def reload(*args)
  super(*args).tap do
    columns_loaded.clear
    columns_to_load_on_demand.each do |attr_name|
      if @attributes.respond_to?(:reset)
        # 4.2 and above
        @attributes.reset(attr_name)
      else
        # 4.1 and earlier
        @attributes.delete(attr_name)
      end
    end
  end
end