Module: OccamsRecord::Results
- Defined in:
- lib/occams-record/results.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 then :deserialize 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 includes a user-defined module.
21 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 64 65 66 67 |
# File 'lib/occams-record/results.rb', line 21 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_name = model ? model.name : nil self.table_name = model ? model.table_name : nil self.primary_key = model&.primary_key&.to_s # Build getters & setters for associations. (We need setters b/c they're set AFTER the row is initialized attr_accessor(*association_names) # Build id getters for associations, e.g. "widget_ids" for "widgets" self.associations.each do |assoc| if (ref = model.reflections[assoc]) and !ref.polymorphic? and (ref.macro == :has_many or ref.macro == :has_and_belongs_to_many) pkey = ref.association_primary_key.to_sym define_method "#{assoc.singularize}_ids" do begin self.send(assoc).map(&pkey).uniq rescue NoMethodError => e raise MissingColumnError.new(self, e.name) end end end end if model # 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 : {} self.columns.each_with_index do |col, idx| type = column_types[col] || model_column_types[col] || raise("OccamsRecord: Column `#{col}` does not exist on model `#{self.model_name}`") case type.type 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 |