Class: ActiveRecord::Result

Inherits:
Object show all
Includes:
Enumerable
Defined in:
activerecord/lib/active_record/result.rb

Overview

Active Record Result

This class encapsulates a result returned from calling #exec_query on any database connection adapter. For example:

result = ActiveRecord::Base.lease_connection.exec_query('SELECT id, title, body FROM posts')
result # => #<ActiveRecord::Result:0xdeadbeef>

# Get the column names of the result:
result.columns
# => ["id", "title", "body"]

# Get the record values of the result:
result.rows
# => [[1, "title_1", "body_1"],
      [2, "title_2", "body_2"],
      ...
     ]

# Get an array of hashes representing the result (column => value):
result.to_a
# => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
      {"id" => 2, "title" => "title_2", "body" => "body_2"},
      ...
     ]

# Get the number of rows affected by the query:
result = ActiveRecord::Base.lease_connection.exec_query('INSERT INTO posts (title, body) VALUES ("title_3", "body_3"), ("title_4", "body_4")')
result.affected_rows
# => 2

# ActiveRecord::Result also includes Enumerable.
result.each do |row|
  puts row['title'] + " " + row['body']
end

Defined Under Namespace

Classes: IndexedRow

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

#as_json, #compact_blank, #exclude?, #excluding, #in_order_of, #including, #index_by, #index_with, #many?, #maximum, #minimum, #pick, #pluck, #sole

Constructor Details

#initialize(columns, rows, column_types = nil, affected_rows: nil) ⇒ Result

Returns a new instance of Result.



107
108
109
110
111
112
113
114
115
116
117
# File 'activerecord/lib/active_record/result.rb', line 107

def initialize(columns, rows, column_types = nil, affected_rows: nil)
  # We freeze the strings to prevent them getting duped when
  # used as keys in ActiveRecord::Base's @attributes hash
  @columns      = columns.each(&:-@).freeze
  @rows         = rows
  @hash_rows    = nil
  @column_types = column_types.freeze
  @types_hash   = nil
  @column_indexes = nil
  @affected_rows = affected_rows
end

Instance Attribute Details

#affected_rowsObject (readonly)

Returns the value of attribute affected_rows.



97
98
99
# File 'activerecord/lib/active_record/result.rb', line 97

def affected_rows
  @affected_rows
end

#columnsObject (readonly)

Returns the value of attribute columns.



97
98
99
# File 'activerecord/lib/active_record/result.rb', line 97

def columns
  @columns
end

#rowsObject (readonly)

Returns the value of attribute rows.



97
98
99
# File 'activerecord/lib/active_record/result.rb', line 97

def rows
  @rows
end

Class Method Details

.empty(async: false, affected_rows: nil) ⇒ Object

:nodoc:



99
100
101
102
103
104
105
# File 'activerecord/lib/active_record/result.rb', line 99

def self.empty(async: false, affected_rows: nil) # :nodoc:
  if async
    FutureResult.wrap(new(EMPTY_ARRAY, EMPTY_ARRAY, EMPTY_HASH, affected_rows: affected_rows)).freeze
  else
    new(EMPTY_ARRAY, EMPTY_ARRAY, EMPTY_HASH, affected_rows: affected_rows).freeze
  end
end

Instance Method Details

#[](idx) ⇒ Object



155
156
157
# File 'activerecord/lib/active_record/result.rb', line 155

def [](idx)
  hash_rows[idx]
end

#cancelObject

:nodoc:



186
187
188
# File 'activerecord/lib/active_record/result.rb', line 186

def cancel # :nodoc:
  self
end

#cast_values(type_overrides = nil) ⇒ Object

:nodoc:



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'activerecord/lib/active_record/result.rb', line 190

def cast_values(type_overrides = nil) # :nodoc:
  if columns.one?
    # Separated to avoid allocating an array per row

    type = if type_overrides.is_a?(Array)
      type_overrides.first
    else
      column_type(columns.first, 0, type_overrides)
    end

    rows.map do |(value)|
      type.deserialize(value)
    end
  else
    types = if type_overrides.is_a?(Array)
      type_overrides
    else
      columns.map.with_index { |name, i| column_type(name, i, type_overrides) }
    end

    rows.map do |values|
      Array.new(values.size) { |i| types[i].deserialize(values[i]) }
    end
  end
end

#column_indexesObject

:nodoc:



228
229
230
231
232
233
234
235
236
237
238
239
# File 'activerecord/lib/active_record/result.rb', line 228

def column_indexes # :nodoc:
  @column_indexes ||= begin
    index = 0
    hash = {}
    length = columns.length
    while index < length
      hash[columns[index]] = index
      index += 1
    end
    hash.freeze
  end
end

#column_typesObject

Returns the ActiveRecord::Type type of all columns. Note that not all database adapters return the result types, so the hash may be empty.



167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'activerecord/lib/active_record/result.rb', line 167

def column_types
  if @column_types
    @types_hash ||= begin
      types = {}
      @columns.each_with_index do |name, index|
        type = @column_types[index] || Type.default_value
        types[name] = types[index] = type
      end
      types.freeze
    end
  else
    EMPTY_HASH
  end
end

#each(&block) ⇒ Object

Calls the given block once for each element in row collection, passing row as parameter. Each row is a Hash-like, read only object.

To get real hashes, use .to_a.each.

Returns an Enumerator if no block is given.



135
136
137
138
139
140
141
# File 'activerecord/lib/active_record/result.rb', line 135

def each(&block)
  if block_given?
    hash_rows.each(&block)
  else
    hash_rows.to_enum { @rows.size }
  end
end

#empty?Boolean

Returns true if there are no records, otherwise false.

Returns:

  • (Boolean)


144
145
146
# File 'activerecord/lib/active_record/result.rb', line 144

def empty?
  rows.empty?
end

#freezeObject

:nodoc:



221
222
223
224
225
226
# File 'activerecord/lib/active_record/result.rb', line 221

def freeze # :nodoc:
  hash_rows.freeze
  indexed_rows
  column_types
  super
end

#includes_column?(name) ⇒ Boolean

Returns true if this result set includes the column named name

Returns:

  • (Boolean)


120
121
122
# File 'activerecord/lib/active_record/result.rb', line 120

def includes_column?(name)
  @columns.include? name
end

#indexed_rowsObject

:nodoc:



241
242
243
244
245
246
# File 'activerecord/lib/active_record/result.rb', line 241

def indexed_rows # :nodoc:
  @indexed_rows ||= begin
    columns = column_indexes
    @rows.map { |row| IndexedRow.new(columns, row) }.freeze
  end
end

#initialize_copy(other) ⇒ Object



216
217
218
219
# File 'activerecord/lib/active_record/result.rb', line 216

def initialize_copy(other)
  @rows = rows.dup
  @hash_rows    = nil
end

#last(n = nil) ⇒ Object

Returns the last record from the rows collection.



160
161
162
# File 'activerecord/lib/active_record/result.rb', line 160

def last(n = nil)
  n ? hash_rows.last(n) : hash_rows.last
end

#lengthObject

Returns the number of elements in the rows array.



125
126
127
# File 'activerecord/lib/active_record/result.rb', line 125

def length
  @rows.length
end

#resultObject

:nodoc:



182
183
184
# File 'activerecord/lib/active_record/result.rb', line 182

def result # :nodoc:
  self
end

#to_aryObject Also known as: to_a

Returns an array of hashes representing each row record.



149
150
151
# File 'activerecord/lib/active_record/result.rb', line 149

def to_ary
  hash_rows
end