Module: OccamsRecord::Results
- Defined in:
- lib/occams-record/results/results.rb,
lib/occams-record/results/row.rb
Overview
Classes and methods for handing query results.
Defined Under Namespace
Classes: Row
Constant Summary collapse
- CASTER =
ActiveRecord’s internal type casting API changes from version to version.
case ActiveRecord::VERSION::MAJOR when 4 then :type_cast_from_database when 5, 6 then :deserialize else raise "OccamsRecord::Results::CASTER does yet support this version of ActiveRecord" end
Class Method Summary collapse
-
.klass(column_names, column_types, association_names = [], model: nil, modules: nil) ⇒ OccamsRecord::Results::Row
Dynamically build a class for a specific set of result rows.
Class Method Details
.klass(column_names, column_types, association_names = [], model: nil, modules: nil) ⇒ OccamsRecord::Results::Row
Dynamically build a class for a specific set of result rows. It inherits from OccamsRecord::Results::Row, and optionall prepends user-defined modules.
22 23 24 25 26 27 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 62 63 |
# File 'lib/occams-record/results/results.rb', line 22 def self.klass(column_names, column_types, association_names = [], model: nil, modules: nil) Class.new(Results::Row) do Array(modules).each { |mod| prepend mod } if modules self.columns = column_names.map(&:to_s) self.associations = association_names.map(&:to_s) self._model = model self.model_name = model ? model.name : nil self.table_name = model ? model.table_name : nil self.primary_key = if model&.primary_key and (pkey = model.primary_key.to_s) and columns.include?(pkey) pkey end # Build getters & setters for associations. (We need setters b/c they're set AFTER the row is initialized attr_accessor(*association_names) # Build a getter for each attribute returned by the query. The values will be type converted on demand. model_column_types = model ? model.attributes_builder.types : nil self.columns.each_with_index do |col, idx| # # NOTE there's lots of variation between DB adapters and AR versions here. Some notes: # * Postgres AR < 6.1 `column_types` will contain entries for every column. # * Postgres AR >= 6.1 `column_types` only contains entries for "exotic" types. Columns with "common" types have already been converted by the PG adapter. # * SQLite `column_types` will always be empty. Some types will have already been convered by the SQLite adapter, but others will depend on # `model_column_types` for converstion. See test/raw_query_test.rb#test_common_types for examples. # * MySQL ? # type = column_types[col] || model_column_types&.[](col) case type&.type when nil define_method(col) { @raw_values[idx] } when :datetime define_method(col) { @cast_values[idx] ||= type.send(CASTER, @raw_values[idx])&.in_time_zone } when :boolean define_method(col) { @cast_values[idx] ||= type.send(CASTER, @raw_values[idx]) } define_method("#{col}?") { !!send(col) } else define_method(col) { @cast_values[idx] ||= type.send(CASTER, @raw_values[idx]) } end end end end |